Hi Jakub,
Jakub Jelinek wrote:
As the testcase shows, gfc_get_symbol_decl can be called multiple times and
we can add the same length multiple times to current or parent function.
As addition of a VAR_DECL to those is done by chaining it into the
DECL_CHAIN linked list, adding the same VAR_DECL twice means a loop in the
chain (in this testcase DECL_CHAIN referencing the containing VAR_DECL, but
it could be longer loop). Any such loop is a bug and e.g. LTO is very upset
about that.
Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux, ok for
trunk?
OK – thanks for the patch.
Tobias
2019-01-18 Jakub Jelinek <ja...@redhat.com>
PR fortran/88902
* trans-decl.c (gfc_get_symbol_decl): Don't add length to function
or parent function if it has been added there already.
* gfortran.dg/pr88902.f90: New test.
--- gcc/fortran/trans-decl.c.jj 2019-01-16 09:35:08.000000000 +0100
+++ gcc/fortran/trans-decl.c 2019-01-18 13:03:07.073419557 +0100
@@ -1572,13 +1572,17 @@ gfc_get_symbol_decl (gfc_symbol * sym)
if (VAR_P (length) && DECL_FILE_SCOPE_P (length))
{
/* Add the string length to the same context as the symbol. */
- if (DECL_CONTEXT (sym->backend_decl) == current_function_decl)
- gfc_add_decl_to_function (length);
- else
- gfc_add_decl_to_parent_function (length);
+ if (DECL_CONTEXT (length) == NULL_TREE)
+ {
+ if (DECL_CONTEXT (sym->backend_decl)
+ == current_function_decl)
+ gfc_add_decl_to_function (length);
+ else
+ gfc_add_decl_to_parent_function (length);
+ }
- gcc_assert (DECL_CONTEXT (sym->backend_decl) ==
- DECL_CONTEXT (length));
+ gcc_assert (DECL_CONTEXT (sym->backend_decl)
+ == DECL_CONTEXT (length));
gfc_defer_symbol_init (sym);
}
--- gcc/testsuite/gfortran.dg/pr88902.f90.jj 2019-01-18 12:58:03.738394429
+0100
+++ gcc/testsuite/gfortran.dg/pr88902.f90 2019-01-18 12:59:06.971357361
+0100
@@ -0,0 +1,6 @@
+! PR fortran/88902
+! { dg-do compile }
+! { dg-require-effective-target lto }
+! { dg-options "-flto --param ggc-min-heapsize=0" }
+
+include 'pr50069_2.f90'
Jakub