diff options
author | Luc Van Oostenryck <luc.vanoostenryck@gmail.com> | 2019-11-18 22:34:41 +0100 |
---|---|---|
committer | Luc Van Oostenryck <luc.vanoostenryck@gmail.com> | 2019-11-19 21:05:56 +0100 |
commit | 009181de300b2f0e6f9e64d4694e07aa12808c57 (patch) | |
tree | 869ba7208ffb2f1b8d965ba761c3f44e8a291f0c | |
parent | 2c5eeff0f1741761196b8b2cfc86b71ef9ef9548 (diff) | |
download | sparse-009181de300b2f0e6f9e64d4694e07aa12808c57.tar.gz |
fix assignment check with function attribute
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@gmail.com>
-rw-r--r-- | evaluate.c | 8 | ||||
-rw-r--r-- | symbol.h | 2 |
2 files changed, 8 insertions, 2 deletions
@@ -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; @@ -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 */ |