aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Uecker <uecker@tugraz.at>2024-05-18 14:40:02 +0200
committerMartin Uecker <uecker@tugraz.at>2024-05-24 17:01:11 +0200
commit9f1798c1a93257526196a3c19828e40fb28ac551 (patch)
treec3d3199b8a3f87e7d2797096262200e8131c3a1f
parentdae606a11eb99814e452b49241fa76f7678f53b8 (diff)
downloadgcc-9f1798c1a93257526196a3c19828e40fb28ac551.zip
gcc-9f1798c1a93257526196a3c19828e40fb28ac551.tar.gz
gcc-9f1798c1a93257526196a3c19828e40fb28ac551.tar.bz2
c: Fix for some variably modified types not being recognized [PR114831]
We did not evaluate expressions with variably modified types correctly in typeof and did not produce warnings when jumping over declarations using typeof. After addressof or array-to-pointer decay we construct new pointer types that have to be marked variably modified if the pointer target is variably modified. 2024-05-18 Martin Uecker <uecker@tugraz.at> PR c/114831 gcc/c/ * c-typeck.cc (array_to_pointer_conversion, build_unary_op): Propagate flag to pointer target. gcc/testsuite/ * gcc.dg/pr114831-1.c: New test. * gcc.dg/pr114831-2.c: New test. * gcc.dg/gnu23-varmod-1.c: New test. * gcc.dg/gnu23-varmod-2.c: New test.
-rw-r--r--gcc/c/c-typeck.cc9
-rw-r--r--gcc/testsuite/gcc.dg/gnu23-varmod-1.c12
-rw-r--r--gcc/testsuite/gcc.dg/gnu23-varmod-2.c16
-rw-r--r--gcc/testsuite/gcc.dg/pr114831-1.c27
-rw-r--r--gcc/testsuite/gcc.dg/pr114831-2.c16
5 files changed, 80 insertions, 0 deletions
diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc
index 7ecca9f..2d09235 100644
--- a/gcc/c/c-typeck.cc
+++ b/gcc/c/c-typeck.cc
@@ -1891,8 +1891,12 @@ array_to_pointer_conversion (location_t loc, tree exp)
copy_warning (exp, orig_exp);
+ bool varmod = C_TYPE_VARIABLY_MODIFIED (restype);
+
ptrtype = build_pointer_type (restype);
+ C_TYPE_VARIABLY_MODIFIED (ptrtype) = varmod;
+
if (INDIRECT_REF_P (exp))
return convert (ptrtype, TREE_OPERAND (exp, 0));
@@ -4630,6 +4634,7 @@ build_unary_op (location_t location, enum tree_code code, tree xarg,
tree eptype = NULL_TREE;
const char *invalid_op_diag;
bool int_operands;
+ bool varmod;
int_operands = EXPR_INT_CONST_OPERANDS (xarg);
if (int_operands)
@@ -5113,8 +5118,12 @@ build_unary_op (location_t location, enum tree_code code, tree xarg,
gcc_assert (TREE_CODE (arg) != COMPONENT_REF
|| !DECL_C_BIT_FIELD (TREE_OPERAND (arg, 1)));
+ varmod = C_TYPE_VARIABLY_MODIFIED (argtype);
+
argtype = build_pointer_type (argtype);
+ C_TYPE_VARIABLY_MODIFIED (argtype) = varmod;
+
/* ??? Cope with user tricks that amount to offsetof. Delete this
when we have proper support for integer constant expressions. */
val = get_base_address (arg);
diff --git a/gcc/testsuite/gcc.dg/gnu23-varmod-1.c b/gcc/testsuite/gcc.dg/gnu23-varmod-1.c
new file mode 100644
index 0000000..add10d1
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/gnu23-varmod-1.c
@@ -0,0 +1,12 @@
+/* { dg-do compile }
+ * { dg-options "-std=gnu23" } */
+
+int foo(int n)
+{
+ int (*a(void))[n] { return 0; };
+ goto err; /* { dg-error "jump into scope" "variably modified" } */
+ typeof((n++,a)) b2;
+err:
+ return n;
+}
+
diff --git a/gcc/testsuite/gcc.dg/gnu23-varmod-2.c b/gcc/testsuite/gcc.dg/gnu23-varmod-2.c
new file mode 100644
index 0000000..c36af1d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/gnu23-varmod-2.c
@@ -0,0 +1,16 @@
+/* { dg-do run }
+ * { dg-options "-std=gnu23" } */
+
+int foo(int n)
+{
+ int (*a(void))[n] { return 0; };
+ typeof((n++,a)) b2;
+ return n;
+}
+
+int main()
+{
+ if (2 != foo(1))
+ __builtin_abort();
+}
+
diff --git a/gcc/testsuite/gcc.dg/pr114831-1.c b/gcc/testsuite/gcc.dg/pr114831-1.c
new file mode 100644
index 0000000..ed30a49
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr114831-1.c
@@ -0,0 +1,27 @@
+/* { dg-do compile }
+ * { dg-options "-std=c23" } */
+
+void f(int n)
+{
+ int a[n];
+ goto foo; /* { dg-error "jump into scope" "variably modified" } */
+ typeof(a) b1;
+foo:
+}
+
+void g(int n)
+{
+ int a2[1][n];
+ goto foo; /* { dg-error "jump into scope" "variably modified" } */
+ typeof((n++,a2)) b2;
+foo:
+}
+
+void h(int n)
+{
+ int a[n];
+ typeof(a) b1;
+ goto foo; /* { dg-error "jump into scope" "variably modified" } */
+ typeof(&b1) b;
+foo:
+}
diff --git a/gcc/testsuite/gcc.dg/pr114831-2.c b/gcc/testsuite/gcc.dg/pr114831-2.c
new file mode 100644
index 0000000..ecfd879
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr114831-2.c
@@ -0,0 +1,16 @@
+/* { dg-do run }
+ * { dg-options "-std=c23" } */
+
+int foo(int n)
+{
+ int a[1][n];
+ typeof((n++,a)) b2;
+ return n;
+}
+
+int main()
+{
+ if (2 != foo(1))
+ __builtin_abort();
+}
+