From: Sergei Trofimovich <siarh...@google.com>

In PR ipa/96291 the test contained an SCC with one
unoptimized function. This tricked ipa-cp into NULL dereference.

has_undead_caller_from_outside_scc_p() did not take into account
that unoptimized funtions don't have IPA summary analysis. And
dereferenced NULL pointer causing an ICE.

gcc/
        PR ipa/96291
        * ipa-cp.c (has_undead_caller_from_outside_scc_p): Consider
        unoptimized callers as undead.

gcc/testsuite/
        PR ipa/96291
        * gcc.dg/lto/pr96291_0.c: New testcase.
        * gcc.dg/lto/pr96291_1.c: Support file.
        * gcc.dg/lto/pr96291_2.c: Likewise.
        * gcc.dg/lto/pr96291.h: Likewise.
---
 gcc/ipa-cp.c                         |  5 +++--
 gcc/testsuite/gcc.dg/lto/pr96291.h   |  4 ++++
 gcc/testsuite/gcc.dg/lto/pr96291_0.c | 11 +++++++++++
 gcc/testsuite/gcc.dg/lto/pr96291_1.c |  3 +++
 gcc/testsuite/gcc.dg/lto/pr96291_2.c |  7 +++++++
 5 files changed, 28 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/lto/pr96291.h
 create mode 100644 gcc/testsuite/gcc.dg/lto/pr96291_0.c
 create mode 100644 gcc/testsuite/gcc.dg/lto/pr96291_1.c
 create mode 100644 gcc/testsuite/gcc.dg/lto/pr96291_2.c

diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c
index b0c8f405260..fe010ff457c 100644
--- a/gcc/ipa-cp.c
+++ b/gcc/ipa-cp.c
@@ -5667,8 +5667,9 @@ has_undead_caller_from_outside_scc_p (struct cgraph_node 
*node,
          (has_undead_caller_from_outside_scc_p, NULL, true))
       return true;
     else if (!ipa_edge_within_scc (cs)
-            && !IPA_NODE_REF (cs->caller)->node_dead)
-      return true;
+            && (!IPA_NODE_REF (cs->caller) /* Unoptimized caller.  */
+                || !IPA_NODE_REF (cs->caller)->node_dead))
+         return true;
   return false;
 }
 
diff --git a/gcc/testsuite/gcc.dg/lto/pr96291.h 
b/gcc/testsuite/gcc.dg/lto/pr96291.h
new file mode 100644
index 00000000000..70eb3cb71b8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/lto/pr96291.h
@@ -0,0 +1,4 @@
+void e(void);
+void f(void);
+void a(void *, void *);
+void c(int);
diff --git a/gcc/testsuite/gcc.dg/lto/pr96291_0.c 
b/gcc/testsuite/gcc.dg/lto/pr96291_0.c
new file mode 100644
index 00000000000..07e63038e03
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/lto/pr96291_0.c
@@ -0,0 +1,11 @@
+/* { dg-lto-do link } */
+
+#include "pr96291.h"
+
+static void * b;
+void c(int d) {
+  f();
+  a(b, b);
+}
+
+void e(void) { c(0); }
diff --git a/gcc/testsuite/gcc.dg/lto/pr96291_1.c 
b/gcc/testsuite/gcc.dg/lto/pr96291_1.c
new file mode 100644
index 00000000000..44744a94941
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/lto/pr96291_1.c
@@ -0,0 +1,3 @@
+#include "pr96291.h"
+
+void f(void) { c(0); }
diff --git a/gcc/testsuite/gcc.dg/lto/pr96291_2.c 
b/gcc/testsuite/gcc.dg/lto/pr96291_2.c
new file mode 100644
index 00000000000..5febffbb00c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/lto/pr96291_2.c
@@ -0,0 +1,7 @@
+/* { dg-options {-O0} } */
+
+#include "pr96291.h"
+
+void a(void * a1, void * a2) { e(); }
+
+int main(){}
-- 
2.27.0

Reply via email to