aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
-rw-r--r--evaluate.c13
-rw-r--r--validation/eval/unqual-cast.c14
2 files changed, 27 insertions, 0 deletions
diff --git a/evaluate.c b/evaluate.c
index 43a61169..c39f9ec7 100644
--- a/evaluate.c
+++ b/evaluate.c
@@ -61,6 +61,18 @@ static inline int valid_subexpr_type(struct expression *expr)
&& valid_expr_type(expr->right);
}
+static struct symbol *unqualify_type(struct symbol *ctype)
+{
+ if (ctype->type == SYM_NODE && (ctype->ctype.modifiers & MOD_QUALIFIER)) {
+ struct symbol *unqual = alloc_symbol(ctype->pos, 0);
+
+ *unqual = *ctype;
+ unqual->ctype.modifiers &= ~MOD_QUALIFIER;
+ return unqual;
+ }
+ return ctype;
+}
+
static struct symbol *evaluate_symbol_expression(struct expression *expr)
{
struct expression *addr;
@@ -3025,6 +3037,7 @@ static struct symbol *evaluate_cast(struct expression *expr)
return evaluate_compound_literal(expr, source);
ctype = examine_symbol_type(expr->cast_type);
+ ctype = unqualify_type(ctype);
expr->ctype = ctype;
expr->cast_type = ctype;
diff --git a/validation/eval/unqual-cast.c b/validation/eval/unqual-cast.c
new file mode 100644
index 00000000..4106ec3b
--- /dev/null
+++ b/validation/eval/unqual-cast.c
@@ -0,0 +1,14 @@
+#define cvr const volatile restrict
+
+_Static_assert([typeof((cvr int) 0)] == [int]);
+_Static_assert([typeof((cvr int *) 0)] == [cvr int *]);
+
+static int *function(volatile int x)
+{
+ extern typeof((typeof(x)) (x)) y;
+ return &y;
+}
+
+/*
+ * check-name: unqual-cast
+ */