It's OK to assign a non-qualified type to the corresponding const- or -volatile-qualified type (same for 'restrict'). For modifiers like __pure or __noreturn, it's the opposite: it's OK to assign the qualified version to the corresponding non-qualified type. Allow this by using type_difference() with the appropriate mask when checking assignments. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@xxxxxxxxx> --- evaluate.c | 8 ++++++-- symbol.h | 2 ++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/evaluate.c b/evaluate.c index b9d3cfe3c..863750fab 100644 --- a/evaluate.c +++ b/evaluate.c @@ -658,7 +658,7 @@ static struct symbol *evaluate_ptr_add(struct expression *expr, struct symbol *i static void examine_fn_arguments(struct symbol *fn); -#define MOD_IGN (MOD_QUALIFIER | MOD_PURE) +#define MOD_IGN (MOD_QUALIFIER | MOD_FUN_ATTR) const char *type_difference(struct ctype *c1, struct ctype *c2, unsigned long mod1, unsigned long mod2) @@ -1429,6 +1429,7 @@ static int check_assignment_types(struct symbol *target, struct expression **rp, if (tclass == TYPE_PTR) { unsigned long mod1, mod2; + unsigned long modl, modr; struct symbol *b1, *b2; // NULL pointer is always OK int is_null = is_null_pointer_constant(*rp); @@ -1471,7 +1472,10 @@ static int check_assignment_types(struct symbol *target, struct expression **rp, goto Cast; } /* It's OK if the target is more volatile or const than the source */ - *typediff = type_difference(&t->ctype, &s->ctype, 0, mod1); + /* It's OK if the source is more pure/noreturn than the target */ + modr = mod1 & ~MOD_REV_QUAL; + modl = mod2 & MOD_REV_QUAL; + *typediff = type_difference(&t->ctype, &s->ctype, modl, modr); if (*typediff) return 0; return 1; diff --git a/symbol.h b/symbol.h index 516b61361..2465d6d88 100644 --- a/symbol.h +++ b/symbol.h @@ -253,6 +253,8 @@ struct symbol { #define MOD_TYPEOF (MOD_QUALIFIER | MOD_NOCAST | MOD_SPECIFIER) /* modifiers for funtion attributes */ #define MOD_FUN_ATTR (MOD_PURE|MOD_NORETURN) +/* like cvr-qualifiers but 'reversed' (OK: source <= target) */ +#define MOD_REV_QUAL (MOD_PURE|MOD_NORETURN) /* Current parsing/evaluation function */ -- 2.24.0