diff options
author | Richard Biener <rguenther@suse.de> | 2019-11-20 07:33:19 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2019-11-20 07:33:19 +0000 |
commit | 3e00ba47b932a13b57061b2d2c95c768ab811d1b (patch) | |
tree | bb2b932e36924ca3737f2da2a580c0a839e4b93a /gcc | |
parent | 54bf2539c55b886ea60d407a7ef2f56f0a19e861 (diff) | |
download | gcc-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/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/builtins.c | 3 | ||||
-rw-r--r-- | gcc/c/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/c/c-decl.c | 17 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/torture/pr92088-1.c | 22 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/torture/pr92088-2.c | 17 |
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 (); +} |