Re: [C PATCH] Fix for some variably modified types not being recognized [PR114831]

2024-05-20 Thread Joseph Myers
On Sat, 18 May 2024, Martin Uecker wrote:

> We did not propagate C_TYPE_VARIABLY_MODIFIED to pointers in all
> cases.   I added this directly in two places, but maybe we should
> check all cases of build_pointer_type or integrate this into 
> c_build_pointer_type and use this everywhere (but I do not fully 
> understand the pointer mode logic there).

This is OK.  I think there's at least one further bug in this area: 
composite types of pointer types (which happen to use 
build_pointer_type_for_mode) don't seem to propagate 
C_TYPE_VARIABLY_MODIFIED either.  Maybe there are other cases as well; 
checking all uses of build_pointer_type functions would make sense.

-- 
Joseph S. Myers
josmy...@redhat.com

Re: [C PATCH] Fix for some variably modified types not being recognized [PR114831]

2024-05-18 Thread Martin Uecker


(correct email)

> We did not propagate C_TYPE_VARIABLY_MODIFIED to pointers in all
> cases.   I added this directly in two places, but maybe we should
> check all cases of build_pointer_type or integrate this into 
> c_build_pointer_type and use this everywhere (but I do not fully 
> understand the pointer mode logic there).
> 
> 
> Bootstrapped and regession tested on x86_64.
> 
> 
> 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  
> 
> 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.
> 
> diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc
> index 7ecca9f58c6..2d092357e0f 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 000..add10d13573
> --- /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 000..c36af1d1647
> --- /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 000..ed30a494b3c
> --- /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() 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 000..ecfd87988c2
> --- /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();
> +}
> +
> 



[C PATCH] Fix for some variably modified types not being recognized [PR114831]

2024-05-18 Thread Martin Uecker


We did not propagate C_TYPE_VARIABLY_MODIFIED to pointers in all
cases.   I added this directly in two places, but maybe we should
check all cases of build_pointer_type or integrate this into 
c_build_pointer_type and use this everywhere (but I do not fully 
understand the pointer mode logic there).


Bootstrapped and regession tested on x86_64.


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  

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.

diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc
index 7ecca9f58c6..2d092357e0f 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 000..add10d13573
--- /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 000..c36af1d1647
--- /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 000..ed30a494b3c
--- /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() 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 000..ecfd87988c2
--- /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();
+}
+