]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c: Fix for some variably modified types not being recognized [PR114831]
authorMartin Uecker <uecker@tugraz.at>
Sat, 18 May 2024 12:40:02 +0000 (14:40 +0200)
committerMartin Uecker <uecker@tugraz.at>
Fri, 24 May 2024 15:01:11 +0000 (17:01 +0200)
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.

gcc/c/c-typeck.cc
gcc/testsuite/gcc.dg/gnu23-varmod-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gnu23-varmod-2.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/pr114831-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/pr114831-2.c [new file with mode: 0644]

index 7ecca9f58c684aeaca5e7276fb1fc297eff78eaf..2d092357e0f9c89b2e501268c66bf2bd3d23cf49 100644 (file)
@@ -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 (file)
index 0000000..add10d1
--- /dev/null
@@ -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 (file)
index 0000000..c36af1d
--- /dev/null
@@ -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 (file)
index 0000000..ed30a49
--- /dev/null
@@ -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 (file)
index 0000000..ecfd879
--- /dev/null
@@ -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();
+}
+