[v2] ipa/96291: don't crash on unoptimized lto functions

Message ID 20200727210734.1587-1-slyfox@gentoo.org
State New
Headers show
Series
  • [v2] ipa/96291: don't crash on unoptimized lto functions
Related show

Commit Message

xionghu luo via Gcc-patches July 27, 2020, 9:07 p.m.
From: Sergei Trofimovich <siarheit@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

-- 
2.27.0

Comments

Richard Biener July 28, 2020, 7:53 a.m. | #1
On Mon, 27 Jul 2020, Sergei Trofimovich wrote:

> From: Sergei Trofimovich <siarheit@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.


OK.  The dg-options -O0 use in _2.c looks exactly correct.

Thanks,
Richard.

> 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(){}

> 


-- 
Richard Biener <rguenther@suse.de>
SUSE Software Solutions Germany GmbH, Maxfeldstrasse 5, 90409 Nuernberg,
Germany; GF: Felix Imendörffer; HRB 36809 (AG Nuernberg)

Patch

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(){}