re PR c/92088 (aggregates with VLAs and nested functions are broken)
authorRichard Biener <rguenther@suse.de>
Wed, 20 Nov 2019 07:33:19 +0000 (07:33 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Wed, 20 Nov 2019 07:33:19 +0000 (07:33 +0000)
2019-11-20  Richard Biener  <rguenther@suse.de>

PR c/92088
c/
* c-decl.c (grokdeclarator): Prevent inlining of nested
function with VLA arguments.

* builtins.c (compute_objsize): Deal with VLAs.

* gcc.dg/torture/pr92088-1.c: New testcase.
* gcc.dg/torture/pr92088-2.c: Likewise.

From-SVN: r278477

gcc/ChangeLog
gcc/builtins.c
gcc/c/ChangeLog
gcc/c/c-decl.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/torture/pr92088-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/torture/pr92088-2.c [new file with mode: 0644]

index d6671a7..c2c82d3 100644 (file)
@@ -1,3 +1,8 @@
+2019-11-20  Richard Biener  <rguenther@suse.de>
+
+       PR c/92088
+       * builtins.c (compute_objsize): Deal with VLAs.
+
 2019-11-19  Pat Haugen  <pthaugen@us.ibm.com>
 
        * config/rs6000/rs6000.c (move_to_end_of_ready): New, factored out
index f94151b..50909af 100644 (file)
@@ -3707,7 +3707,8 @@ compute_objsize (tree dest, int ostype, tree *pdecl /* = NULL */)
   if (DECL_P (ref))
     {
       *pdecl = ref;
-      return DECL_SIZE_UNIT (ref);
+      if (tree size = DECL_SIZE_UNIT (ref))
+       return TREE_CODE (size) == INTEGER_CST ? size : NULL_TREE;
     }
 
   tree type = TREE_TYPE (dest);
index 3f42e40..7b37842 100644 (file)
@@ -1,3 +1,9 @@
+2019-11-20  Richard Biener  <rguenther@suse.de>
+
+       PR c/92088
+       * c-decl.c (grokdeclarator): Prevent inlining of nested
+       function with VLA arguments.
+
 2019-11-20  Joseph Myers  <joseph@codesourcery.com>
 
        * c-decl.c (c_warn_type_attributes): New function.
index d153de2..caa9c85 100644 (file)
@@ -7405,6 +7405,23 @@ grokdeclarator (const struct c_declarator *declarator,
                    "no linkage");
       }
 
+    /* For nested functions disqualify ones taking VLAs by value
+       from inlining since the middle-end cannot deal with this.
+       ???  We should arrange for those to be passed by reference
+       with emitting the copy on the caller side in the frontend.  */
+    if (storage_class == csc_none
+       && TREE_CODE (type) == FUNCTION_TYPE)
+      for (tree al = TYPE_ARG_TYPES (type); al; al = TREE_CHAIN (al))
+       {
+         tree arg = TREE_VALUE (al);
+         if (arg != error_mark_node
+             && C_TYPE_VARIABLE_SIZE (arg))
+           {
+             DECL_UNINLINABLE (decl) = 1;
+             break;
+           }
+       }
+
     /* Record `register' declaration for warnings on &
        and in case doing stupid register allocation.  */
 
index 0964e44..8198d22 100644 (file)
@@ -1,3 +1,9 @@
+2019-11-20  Richard Biener  <rguenther@suse.de>
+
+       PR c/92088
+       * gcc.dg/torture/pr92088-1.c: New testcase.
+       * gcc.dg/torture/pr92088-2.c: Likewise.
+
 2019-11-20  Paolo Carlini  <paolo.carlini@oracle.com>
 
        * g++.dg/warn/multiple-sign-compare-warn-1.C: New.
diff --git a/gcc/testsuite/gcc.dg/torture/pr92088-1.c b/gcc/testsuite/gcc.dg/torture/pr92088-1.c
new file mode 100644 (file)
index 0000000..b56f8ad
--- /dev/null
@@ -0,0 +1,22 @@
+/* { dg-do run } */
+
+int __attribute__((noipa))
+g (char *p)
+{
+  return p[9];
+}
+int main (int argc, char **argv)
+{
+  struct S {
+    char toto[argc + 16];
+  };
+  int f (struct S arg) {
+      __builtin_strcpy(arg.toto, "helloworld");
+      return g (arg.toto);
+  }
+  struct S bob;
+  __builtin_strcpy(bob.toto, "coucoucoucou");
+  if (f(bob) != 'd' || __builtin_strcmp (bob.toto, "coucoucoucou"))
+    __builtin_abort ();
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr92088-2.c b/gcc/testsuite/gcc.dg/torture/pr92088-2.c
new file mode 100644 (file)
index 0000000..a20a01c
--- /dev/null
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+
+void foo(int n)
+{
+  struct X { int a[n]; } y;
+
+  struct X baz (struct X x)
+    {
+      x.a[0] = 1;
+      return x;
+    }
+
+  y.a[0] = 0;
+  y = baz(y);
+  if (y.a[0] != 1)
+    __builtin_abort ();
+}