Fix segfault in inliner with attribute flatten

Message ID 20171211070159.26287-1-andi@firstfloor.org
State New
Headers show
Series
  • Fix segfault in inliner with attribute flatten
Related show

Commit Message

Andi Kleen Dec. 11, 2017, 7:01 a.m.
From: Andi Kleen <ak@linux.intel.com>


This fixes a segfault in gcc 7/8 when building turicreate.

For some reason the node has no decl here, and there is a
crash when checking for attribute flatten.

gcc/:

2017-12-10  Andi Kleen  <ak@linux.intel.com>

	PR ipa/83346
	* ipa-inline.c (ipa_inline): Check for NULL pointer.

gcc/testsuite:

2017-12-10  Andi Kleen  <ak@linux.intel.com>

	* g++.dg/pr83346.C: Add.
---
 gcc/ipa-inline.c               |  3 ++-
 gcc/testsuite/g++.dg/pr83346.C | 32 ++++++++++++++++++++++++++++++++
 2 files changed, 34 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/g++.dg/pr83346.C

-- 
2.15.1

Comments

Richard Biener Dec. 11, 2017, 3:29 p.m. | #1
On Mon, Dec 11, 2017 at 8:01 AM, Andi Kleen <andi@firstfloor.org> wrote:
> From: Andi Kleen <ak@linux.intel.com>

>

> This fixes a segfault in gcc 7/8 when building turicreate.

>

> For some reason the node has no decl here, and there is a

> crash when checking for attribute flatten.


As said in the PR it looks like the order array is corrupted
(a freed entry is re-used with an inline clone).

Honza?

Richard.

> gcc/:

>

> 2017-12-10  Andi Kleen  <ak@linux.intel.com>

>

>         PR ipa/83346

>         * ipa-inline.c (ipa_inline): Check for NULL pointer.

>

> gcc/testsuite:

>

> 2017-12-10  Andi Kleen  <ak@linux.intel.com>

>

>         * g++.dg/pr83346.C: Add.

> ---

>  gcc/ipa-inline.c               |  3 ++-

>  gcc/testsuite/g++.dg/pr83346.C | 32 ++++++++++++++++++++++++++++++++

>  2 files changed, 34 insertions(+), 1 deletion(-)

>  create mode 100644 gcc/testsuite/g++.dg/pr83346.C

>

> diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c

> index 7846e93d119..dcd8a3de1ac 100644

> --- a/gcc/ipa-inline.c

> +++ b/gcc/ipa-inline.c

> @@ -2391,7 +2391,8 @@ ipa_inline (void)

>          entry of cycles, possibly cloning that entry point and

>          try to flatten itself turning it into a self-recursive

>          function.  */

> -      if (lookup_attribute ("flatten",

> +      if (node->decl

> +        && lookup_attribute ("flatten",

>                             DECL_ATTRIBUTES (node->decl)) != NULL)

>         {

>           if (dump_file)

> diff --git a/gcc/testsuite/g++.dg/pr83346.C b/gcc/testsuite/g++.dg/pr83346.C

> new file mode 100644

> index 00000000000..2a916223dc9

> --- /dev/null

> +++ b/gcc/testsuite/g++.dg/pr83346.C

> @@ -0,0 +1,32 @@

> +/* { dg-do compile } */

> +/* { dg-options "-O2" }  */

> +namespace {

> +template <typename, typename a> struct b { a c; };

> +}

> +typedef int d;

> +namespace {

> +namespace {

> +template <typename e, typename = e, typename = e> class ac;

> +typedef ac<char> ad;

> +template <typename, typename, typename> class ac {

> +public:

> +  ~ac();

> +};

> +}

> +typedef ad f;

> +struct g {};

> +enum ag {};

> +class ae {

> +public:

> +  ~ae();

> +  template <typename h> ae(h);

> +  union aj {

> +    b<d, f> *ak;

> +    struct {

> +      ag al;

> +    };

> +  } am;

> +  __attribute__((always_inline)) void an(aj i, ag) { delete i.ak; }

> +} ao = g();

> +__attribute__((always_inline, flatten)) ae::~ae() { an(am, am.al); }

> +}

> --

> 2.15.1

>

Patch

diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c
index 7846e93d119..dcd8a3de1ac 100644
--- a/gcc/ipa-inline.c
+++ b/gcc/ipa-inline.c
@@ -2391,7 +2391,8 @@  ipa_inline (void)
 	 entry of cycles, possibly cloning that entry point and
 	 try to flatten itself turning it into a self-recursive
 	 function.  */
-      if (lookup_attribute ("flatten",
+      if (node->decl
+	 && lookup_attribute ("flatten",
 			    DECL_ATTRIBUTES (node->decl)) != NULL)
 	{
 	  if (dump_file)
diff --git a/gcc/testsuite/g++.dg/pr83346.C b/gcc/testsuite/g++.dg/pr83346.C
new file mode 100644
index 00000000000..2a916223dc9
--- /dev/null
+++ b/gcc/testsuite/g++.dg/pr83346.C
@@ -0,0 +1,32 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O2" }  */
+namespace {
+template <typename, typename a> struct b { a c; };
+}
+typedef int d;
+namespace {
+namespace {
+template <typename e, typename = e, typename = e> class ac;
+typedef ac<char> ad;
+template <typename, typename, typename> class ac {
+public:
+  ~ac();
+};
+}
+typedef ad f;
+struct g {};
+enum ag {};
+class ae {
+public:
+  ~ae();
+  template <typename h> ae(h);
+  union aj {
+    b<d, f> *ak;
+    struct {
+      ag al;
+    };
+  } am;
+  __attribute__((always_inline)) void an(aj i, ag) { delete i.ak; }
+} ao = g();
+__attribute__((always_inline, flatten)) ae::~ae() { an(am, am.al); }
+}