aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
-rw-r--r--symbol.c8
-rw-r--r--symbol.h2
-rw-r--r--validation/typeof-mods.c1
3 files changed, 8 insertions, 3 deletions
diff --git a/symbol.c b/symbol.c
index 92a7a625..a65ad17b 100644
--- a/symbol.c
+++ b/symbol.c
@@ -466,12 +466,16 @@ struct symbol *examine_symbol_type(struct symbol * sym)
case SYM_TYPEOF: {
struct symbol *base = evaluate_expression(sym->initializer);
if (base) {
+ unsigned long mod = 0;
+
if (is_bitfield_type(base))
warning(base->pos, "typeof applied to bitfield type");
- if (base->type == SYM_NODE)
+ if (base->type == SYM_NODE) {
+ mod |= base->ctype.modifiers & MOD_TYPEOF;
base = base->ctype.base_type;
+ }
sym->type = SYM_NODE;
- sym->ctype.modifiers = 0;
+ sym->ctype.modifiers = mod;
sym->ctype.base_type = base;
return examine_node_type(sym);
}
diff --git a/symbol.h b/symbol.h
index afc4e232..51be81fb 100644
--- a/symbol.h
+++ b/symbol.h
@@ -248,6 +248,8 @@ struct symbol {
#define MOD_IGNORE (MOD_TOPLEVEL | MOD_STORAGE | MOD_ADDRESSABLE | \
MOD_ASSIGNED | MOD_USERTYPE | MOD_ACCESSED | MOD_EXPLICITLY_SIGNED)
#define MOD_PTRINHERIT (MOD_VOLATILE | MOD_CONST | MOD_NODEREF | MOD_NORETURN | MOD_NOCAST)
+/* modifiers preserved by typeof() operator */
+#define MOD_TYPEOF (MOD_VOLATILE | MOD_CONST | MOD_NOCAST | MOD_SPECIFIER)
/* Current parsing/evaluation function */
diff --git a/validation/typeof-mods.c b/validation/typeof-mods.c
index 8c98ab8c..9822e96f 100644
--- a/validation/typeof-mods.c
+++ b/validation/typeof-mods.c
@@ -102,7 +102,6 @@ static void test_nocast(void)
/*
* check-name: typeof-mods
- * check-known-to-fail
*
* check-error-start
* check-error-end