Joseph Myers <josmy...@redhat.com> writes:

> Bug 117164 is an ICE on an existing test with -std=gnu23 involving a
> nested function returning a variable-size structure (and I think the
> last bug needing to be resolved before switching to -std=gnu23 as the
> default, as without fixing this would be a clear regression from a
> change in default).
>
> The problem is a GIMPLE verification failure where (after type
> remapping from inlining / cloning) the return type of the function no
> longer exactly matches the type to which it is assigned (these types
> use structural equality, which means GIMPLE verification can't use
> TYPE_CANONICAL and expects an exact match).  Specifically, the nested
> function itself is *not* inlined (the -fno-inline-small-functions in
> the original test nested-func-12.c, I think, or the noinline attribute
> in some of my variant tests), but the function containing it is either
> cloned (the --param ipa-cp-eval-threshold=0 in the original test) or
> inlined.  (I'm not sure what role -fno-guess-branch-probability plays
> in getting the right situation for the ICE; maybe affecting when
> inlining or cloning is considered profitable?)
>
> There is in fact existing code in tree-nested.cc to prevent inlining
> of a function containing a nested function with variably modified
> *argument* types.  I think the same issue of ensuring consistency of
> types means such prevention should also apply for a variably modified
> return type.  Furthermore, exactly the same problem applies for
> cloning for other reasons as it does for inlining.  Thus, change the
> logic to include variably modified return types for nested functions
> alongside those for arguments of those functions as a reason not to
> inline, and also add the noclone attribute in these cases.
>
> Bootstrapped with no regressions for x86-64-pc-linux-gnu.
>
>       PR c/117164
>
> gcc/
>       * tree-nested.cc: Include "attribs.h".
>       (check_for_nested_with_variably_modified): Also return true for
>       variably modified return type.
>       (create_nesting_tree): If check_for_nested_with_variably_modified
>       returns true, also add noclone attribute.
>
> gcc/testsuite/
>       * gcc.dg/nested-func-13.c, gcc.dg/nested-func-14.c:
>       gcc.dg/nested-func-15.c, gcc.dg/nested-func-16.c,
>       gcc.dg/nested-func-17.c: New tests.
>
> diff --git a/gcc/testsuite/gcc.dg/nested-func-13.c 
> b/gcc/testsuite/gcc.dg/nested-func-13.c
> new file mode 100644
> index 000000000000..697a62354109
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/nested-func-13.c
> @@ -0,0 +1,6 @@
> +/* Test nested-func-12.c with -std=gnu17.  */
> +/* { dg-do run } */
> +/* { dg-options "-Ofast --param ipa-cp-eval-threshold=0 
> -fno-guess-branch-probability -fno-inline-small-functions -std=gnu17" } */
> +/* { dg-require-effective-target alloca } */
> +
> +#include "nested-func-12.c"
> diff --git a/gcc/testsuite/gcc.dg/nested-func-14.c 
> b/gcc/testsuite/gcc.dg/nested-func-14.c
> new file mode 100644
> index 000000000000..05a77bdb1a5a
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/nested-func-14.c
> @@ -0,0 +1,6 @@
> +/* Test nested-func-12.c with -std=gnu23.  */
> +/* { dg-do run } */
> +/* { dg-options "-Ofast --param ipa-cp-eval-threshold=0 
> -fno-guess-branch-probability -fno-inline-small-functions -std=gnu23" } */
> +/* { dg-require-effective-target alloca } */
> +
> +#include "nested-func-12.c"
> diff --git a/gcc/testsuite/gcc.dg/nested-func-15.c 
> b/gcc/testsuite/gcc.dg/nested-func-15.c
> new file mode 100644
> index 000000000000..490d69599868
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/nested-func-15.c
> @@ -0,0 +1,29 @@
> +/* Bug 117164: ICE with -std=gnu23 inlining function containing call
> +   to non-inlined nested function returning variable-size struct.  */
> +/* { dg-do run } */

nested-func-12 which exposed the problem, as reported in PR117164, has
assertions on the value of a. This test doesn't, so its value as a
runtime test is questionable as-is.

> +/* { dg-options "-O3 --param ipa-cp-eval-threshold=0 
> -fno-guess-branch-probability -fno-inline-small-functions -std=gnu23" } */
> +/* { dg-require-effective-target alloca } */
> +
> +void
> +foo (int n)
> +{
> +  struct S { int a[n]; };
> +
> +  struct S
> +  fn (void)
> +  {
> +    struct S s;
> +    s.a[0] = 42;
> +    return s;
> +  }
> +
> +  fn ();
> +  fn ();
> +  fn ();
> +}
> +
> +int
> +main (void)
> +{
> +  foo (1);
> +}
>
> [...]

thanks,
sam

Reply via email to