Fix cgraph_node::function_symbol availability compuattion [PR94202]
authorJan Hubicka <jh@suse.cz>
Thu, 19 Mar 2020 23:42:13 +0000 (00:42 +0100)
committerJan Hubicka <jh@suse.cz>
Thu, 19 Mar 2020 23:42:13 +0000 (00:42 +0100)
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  <hubicka@ucw.cz>

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  <hubicka@ucw.cz>

PR ipa/94202
* g++.dg/torture/pr94202.C: New test.

gcc/ChangeLog
gcc/cgraph.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/torture/pr94202.C [new file with mode: 0644]

index e1a778df2022e02feb1fae0566b46ce5668694d2..44e320626a318ee16ac79236d028b43e28f9084c 100644 (file)
@@ -1,3 +1,9 @@
+2020-03-19  Jan Hubicka  <hubicka@ucw.cz>
+
+       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  <hubicka@ucw.cz>
 
        PR ipa/92372
index 9f0774f227f83c2dd6558ea6ef694ab0fa1a2585..b41dea1fccabea7c869c2cfdfef44f07e511f0ea 100644 (file)
@@ -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;
 }
index bde605d2b2fb40ad02917ed6373f31212ed931e9..212c6ffc06efc3b1a9c541d3951b937a07de4b00 100644 (file)
@@ -1,3 +1,8 @@
+2020-03-19  Jan Hubicka  <hubicka@ucw.cz>
+
+       PR ipa/94202
+       * g++.dg/torture/pr94202.C: New test.
+
 2020-03-19  Jakub Jelinek  <jakub@redhat.com>
 
        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 (file)
index 0000000..5ed3dcb
--- /dev/null
@@ -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<S1 *>(x)->v();
+    x->v();
+    m = x;
+  }
+};
+void f() {
+  R r;
+  r.f(new S4);
+  r.f(new S3);
+}