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@xxxxxxxxx> --- linearize.c | 2 +- validation/eval-bad-assign1.c | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) 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) -- 2.23.0