From: Richard Biener Date: Wed, 20 Nov 2019 07:33:19 +0000 (+0000) Subject: re PR c/92088 (aggregates with VLAs and nested functions are broken) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=3e00ba47b932a13b57061b2d2c95c768ab811d1b;p=gcc.git re PR c/92088 (aggregates with VLAs and nested functions are broken) 2019-11-20 Richard Biener 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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d6671a7c1fb..c2c82d354a0 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2019-11-20 Richard Biener + + PR c/92088 + * builtins.c (compute_objsize): Deal with VLAs. + 2019-11-19 Pat Haugen * config/rs6000/rs6000.c (move_to_end_of_ready): New, factored out diff --git a/gcc/builtins.c b/gcc/builtins.c index f94151bd84d..50909af91f9 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 3f42e40896a..7b37842ca5b 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,9 @@ +2019-11-20 Richard Biener + + PR c/92088 + * c-decl.c (grokdeclarator): Prevent inlining of nested + function with VLA arguments. + 2019-11-20 Joseph Myers * c-decl.c (c_warn_type_attributes): New function. diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c index d153de2e2ad..caa9c85897e 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 0964e44ada5..8198d22da50 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2019-11-20 Richard Biener + + PR c/92088 + * gcc.dg/torture/pr92088-1.c: New testcase. + * gcc.dg/torture/pr92088-2.c: Likewise. + 2019-11-20 Paolo Carlini * 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 00000000000..b56f8ad665e --- /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 00000000000..a20a01cd1ce --- /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 (); +}