diff mbox series

[2/2] do not linearize invalid expression

Message ID 20190927014150.38705-3-luc.vanoostenryck@gmail.com (mailing list archive)
State Mainlined, archived
Headers show
Series do not linearize invalid expression | expand

Commit Message

Luc Van Oostenryck Sept. 27, 2019, 1:41 a.m. UTC
Code like:
	int *r;
	r = ({ __builtin_types_compatible_p(long, long); });

triggers the following diagnostics:
	warning: incorrect type in assignment (different base types)
	   expected int *r
	   got long
	warning: unknown expression (4 0)
	warning: unknown expression (4 0)

The first warning is expected but the other two are bogus.

The origin of the problem could be considered as being how
type incompabilities are handled in assignment:
   If an incompatibility is found by compatible_assignment_types()
   - a warning is issued (not an error),
   - the source expression is casted to the destination type,
   - the returned value indicates a problem was detected.
   In the other uses of this function the returned value is simply
   ignored and normal processing continue. This seems logical since
   only a warning is issued and so (thanks to the cast) the
   resulting expression is at least type-coherent.
   However, in evaluate_assignment() the returned value is not
   ignored and the calling function directly returns. This leaves
   the resulting expression without a valid type, as if an error
   occured, unable to be correctly processed further.

However, the real problem is that an expression without a valid
type should never be linearized.

So, in linearize_expression(), refuse to linearize an expression
without a valid type.

Note: if one is interested in doing a maximum of processing,
      including expansion and linearization, check_assignment_types()
      should be modified to distinguish between recoverable and
      non-recoverable type error (those for which the forced
      cast make sense and those for which it doesn't) and
      compatible_assignment_types() modified accordingly (maybe
      issuing a warning in the first case and an error otherwise).

Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
 linearize.c                   | 2 +-
 validation/eval-bad-assign1.c | 1 -
 2 files changed, 1 insertion(+), 2 deletions(-)
diff mbox series

Patch

diff --git a/linearize.c b/linearize.c
index 415bf7e50..d705ffd59 100644
--- a/linearize.c
+++ b/linearize.c
@@ -1864,7 +1864,7 @@  static void linearize_argument(struct entrypoint *ep, struct symbol *arg, int nr
 
 static pseudo_t linearize_expression(struct entrypoint *ep, struct expression *expr)
 {
-	if (!expr)
+	if (!expr || !valid_type(expr->ctype))
 		return VOID;
 
 	current_pos = expr->pos;
diff --git a/validation/eval-bad-assign1.c b/validation/eval-bad-assign1.c
index bce4d3d38..57138c7af 100644
--- a/validation/eval-bad-assign1.c
+++ b/validation/eval-bad-assign1.c
@@ -5,7 +5,6 @@  static void kos(int *r, int a)
 
 /*
  * check-name: eval-bad-assign1
- * check-known-to-fail
  *
  * check-error-start
 eval-bad-assign1.c:3:11: warning: incorrect type in assignment (different base types)