diff mbox series

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 | expand

Commit Message

Andi Kleen Dec. 11, 2017, 7:01 a.m. UTC
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

Comments

Richard Biener Dec. 11, 2017, 3:29 p.m. UTC | #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
>
diff mbox series

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); }
+}