From: Jan Hubicka Date: Thu, 19 Mar 2020 23:42:13 +0000 (+0100) Subject: Fix cgraph_node::function_symbol availability compuattion [PR94202] X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=f7dceb4e658399edfbf8dd0e08ce0c686bfa2c9d;p=gcc.git Fix cgraph_node::function_symbol availability compuattion [PR94202] this fixes ICE in inliner cache sanity check which is caused by very old bug in visibility calculation in cgraph_node::function_symbol and cgraph_node::function_or_virtual_thunk_symbol. In the testcase there is indirect call to a thunk. At begining we correctly see that its body as AVAIL_AVAILABLE but later we inline into the thunk and this turns it to AVAIL_INTERPOSABLE. This is because function_symbol incorrectly overwrites availability parameter by availability of the alias used in the call within thunk, which is a local alias. gcc/ChangeLog: 2020-03-19 Jan Hubicka PR ipa/94202 * cgraph.c (cgraph_node::function_symbol): Fix availability computation. (cgraph_node::function_or_virtual_thunk_symbol): Likewise. gcc/testsuite/ChangeLog: 2020-03-19 Jan Hubicka PR ipa/94202 * g++.dg/torture/pr94202.C: New test. --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e1a778df202..44e320626a3 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2020-03-19 Jan Hubicka + + PR ipa/94202 + * cgraph.c (cgraph_node::function_symbol): Fix availability computation. + (cgraph_node::function_or_virtual_thunk_symbol): Likewise. + 2020-03-19 Jan Hubicka PR ipa/92372 diff --git a/gcc/cgraph.c b/gcc/cgraph.c index 9f0774f227f..b41dea1fcca 100644 --- a/gcc/cgraph.c +++ b/gcc/cgraph.c @@ -3788,16 +3788,13 @@ cgraph_node::function_symbol (enum availability *availability, while (node->thunk.thunk_p) { + enum availability a; + ref = node; node = node->callees->callee; - if (availability) - { - enum availability a; - a = node->get_availability (ref); - if (a < *availability) - *availability = a; - } - node = node->ultimate_alias_target (availability, ref); + node = node->ultimate_alias_target (availability ? &a : NULL, ref); + if (availability && a < *availability) + *availability = a; } return node; } @@ -3818,16 +3815,13 @@ cgraph_node::function_or_virtual_thunk_symbol while (node->thunk.thunk_p && !node->thunk.virtual_offset_p) { + enum availability a; + ref = node; node = node->callees->callee; - if (availability) - { - enum availability a; - a = node->get_availability (ref); - if (a < *availability) - *availability = a; - } - node = node->ultimate_alias_target (availability, ref); + node = node->ultimate_alias_target (availability ? &a : NULL, ref); + if (availability && a < *availability) + *availability = a; } return node; } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index bde605d2b2f..212c6ffc06e 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2020-03-19 Jan Hubicka + + PR ipa/94202 + * g++.dg/torture/pr94202.C: New test. + 2020-03-19 Jakub Jelinek PR gcov-profile/94029 diff --git a/gcc/testsuite/g++.dg/torture/pr94202.C b/gcc/testsuite/g++.dg/torture/pr94202.C new file mode 100644 index 00000000000..5ed3dcbcd18 --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/pr94202.C @@ -0,0 +1,22 @@ +// { dg-additional-options "-w" } +struct S1 { + virtual ~S1(); + virtual void v(); +}; +struct S2: S1 {}; +struct S3: S1, S2 { void v(); }; +struct S4: S3 { void v(); }; +void S4::v() { S3::v(); } +struct R { + S1 * m; + void f(S2 * x) { + static_cast(x)->v(); + x->v(); + m = x; + } +}; +void f() { + R r; + r.f(new S4); + r.f(new S3); +}