Here is a patch which changes the behavior of sizeof
when applied to structs of variable size (a GNU
extension) to evaluate its arguments as it does
for VLAs. This is a breaking change, but it seems
this is required if we want to fix [PR29970] (and
it is also more consistent). Together with the patch
I sent previously (which needs fixing as it breaks Ada)
and another small change, this would fix most
of the examples in PR29970.

Comments?




Evaluate arguments of sizeof that are structs of variable size.

Evaluate arguments of sizeof for all types of variable size
and not just for VLAs. This fixes some issues related to
[PR29970] where statement expressions need to be evaluated
so that the size is well defined.

2021-08-09  Martin Uecker  <muec...@gwdg.de>
    
    gcc/
        PR c/29970
        * c-typeck.c (c_expr_sizeof_expr): Evaluate
        size expressions for structs of variable size.

    gcc/testsuite/
        PR c/29970
        * gcc.dg/vla-stexp-1.c: New test.
       

diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c
index 5d6565bdaa9..c5bf3372321 100644
--- a/gcc/c/c-typeck.c
+++ b/gcc/c/c-typeck.c
@@ -2992,7 +2992,7 @@ c_expr_sizeof_expr (location_t loc, struct c_expr expr)
       c_last_sizeof_loc = loc;
       ret.original_code = SIZEOF_EXPR;
       ret.original_type = NULL;
-      if (c_vla_type_p (TREE_TYPE (folded_expr)))
+      if (C_TYPE_VARIABLE_SIZE (TREE_TYPE (folded_expr)))
        {
          /* sizeof is evaluated when given a vla (C99 6.5.3.4p2).  */
          ret.value = build2 (C_MAYBE_CONST_EXPR, TREE_TYPE (ret.value),
diff --git a/gcc/testsuite/gcc.dg/vla-stexp-01.c 
b/gcc/testsuite/gcc.dg/vla-stexp-01.c
new file mode 100644
index 00000000000..97d66937e9a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vla-stexp-01.c
@@ -0,0 +1,18 @@
+/* PR29970*/
+/* { dg-do run } */
+/* { dg-options "-Wall -O0" } */
+
+int foo(void)
+{
+       int n = 0;
+       return sizeof(*({ n = 10; struct foo { int x[n]; } x; &x; }));
+}
+
+
+int main()
+{
+       if (sizeof(struct foo { int x[10]; }) != foo())
+               __builtin_abort();
+
+       return 0;
+}

Reply via email to