aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2019-11-20 07:33:19 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2019-11-20 07:33:19 +0000
commit3e00ba47b932a13b57061b2d2c95c768ab811d1b (patch)
treebb2b932e36924ca3737f2da2a580c0a839e4b93a /gcc
parent54bf2539c55b886ea60d407a7ef2f56f0a19e861 (diff)
downloadgcc-3e00ba47b932a13b57061b2d2c95c768ab811d1b.zip
gcc-3e00ba47b932a13b57061b2d2c95c768ab811d1b.tar.gz
gcc-3e00ba47b932a13b57061b2d2c95c768ab811d1b.tar.bz2
re PR c/92088 (aggregates with VLAs and nested functions are broken)
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/builtins.c3
-rw-r--r--gcc/c/ChangeLog6
-rw-r--r--gcc/c/c-decl.c17
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr92088-1.c22
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr92088-2.c17
7 files changed, 75 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index d6671a7..c2c82d3 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/builtins.c b/gcc/builtins.c
index f94151b..50909af 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -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);
diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog
index 3f42e40..7b37842 100644
--- a/gcc/c/ChangeLog
+++ b/gcc/c/ChangeLog
@@ -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.
diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c
index d153de2..caa9c85 100644
--- a/gcc/c/c-decl.c
+++ b/gcc/c/c-decl.c
@@ -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. */
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 0964e44..8198d22 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..b56f8ad
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr92088-1.c
@@ -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
index 0000000..a20a01c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr92088-2.c
@@ -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 ();
+}