diff mbox series

rs6000: Fix C++14 vs. C++17 ABI bug on powerpc64le [PR94707]

Message ID 20200422131148.GK2424@tucnak
State New
Headers show
Series rs6000: Fix C++14 vs. C++17 ABI bug on powerpc64le [PR94707] | expand

Commit Message

Jakub Jelinek April 22, 2020, 1:11 p.m. UTC
Hi!

As mentioned in the PR and on IRC, the recently added struct-layout-1.exp
new tests FAIL on powerpc64le-linux (among other targets).
FAIL: tmpdir-g++.dg-struct-layout-1/t032 cp_compat_x_tst.o-cp_compat_y_tst.o execute
FAIL: tmpdir-g++.dg-struct-layout-1/t058 cp_compat_x_tst.o-cp_compat_y_tst.o execute
FAIL: tmpdir-g++.dg-struct-layout-1/t059 cp_compat_x_tst.o-cp_compat_y_tst.o execute
in particular.  The problem is that the presence or absence of the C++17
artificial empty base fields, which have non-zero TYPE_SIZE, but zero
DECL_SIZE, change the ABI decisions, if it is present (-std=c++17), the type
might not be considered homogeneous, while if it is absent (-std=c++14), it
can be.

The following patch fixes that and emits a -Wpsabi inform; perhaps more
often than it could, because the fact that rs6000_discover_homogeneous_aggregate
returns true when it didn't in in GCC 7/8/9 with -std=c++17 doesn't still
mean it will make a different ABI decision, but the warning triggered only
on the test I've changed (the struct-layout-1.exp tests use -w -Wno-psabi
already).

Bootstrapped/regtested on powerpc64le-linux, bootstrapped on powerpc64-linux
where regtest is still pending, but homogeneous aggregates are an ELFv2
thing, so I don't expect it to change anything (and so far no such messages
appear in the testsuite log files).

Ok for trunk?

2020-04-22  Jakub Jelinek  <jakub@redhat.com>

	PR target/94707
	* config/rs6000/rs6000-call.c (rs6000_aggregate_candidate): Add
	CXX17_EMPTY_BASE_SEEN argument.  Pass it to recursive calls.
	Ignore cxx17_empty_base_field_p fields after setting
	*CXX17_EMPTY_BASE_SEEN to true.
	(rs6000_discover_homogeneous_aggregate): Adjust
	rs6000_aggregate_candidate caller.  With -Wpsabi, diagnose homogeneous
	aggregates with C++17 empty base fields.

	* g++.dg/tree-ssa/pr27830.C: Use -Wpsabi -w for -std=c++17 and higher.


	Jakub

Comments

Li, Pan2 via Gcc-patches April 22, 2020, 4:24 p.m. UTC | #1
On 4/22/20 8:11 AM, Jakub Jelinek via Gcc-patches wrote:
> Hi!
>
> As mentioned in the PR and on IRC, the recently added struct-layout-1.exp
> new tests FAIL on powerpc64le-linux (among other targets).
> FAIL: tmpdir-g++.dg-struct-layout-1/t032 cp_compat_x_tst.o-cp_compat_y_tst.o execute
> FAIL: tmpdir-g++.dg-struct-layout-1/t058 cp_compat_x_tst.o-cp_compat_y_tst.o execute
> FAIL: tmpdir-g++.dg-struct-layout-1/t059 cp_compat_x_tst.o-cp_compat_y_tst.o execute
> in particular.  The problem is that the presence or absence of the C++17
> artificial empty base fields, which have non-zero TYPE_SIZE, but zero
> DECL_SIZE, change the ABI decisions, if it is present (-std=c++17), the type
> might not be considered homogeneous, while if it is absent (-std=c++14), it
> can be.
>
> The following patch fixes that and emits a -Wpsabi inform; perhaps more
> often than it could, because the fact that rs6000_discover_homogeneous_aggregate
> returns true when it didn't in in GCC 7/8/9 with -std=c++17 doesn't still
> mean it will make a different ABI decision, but the warning triggered only
> on the test I've changed (the struct-layout-1.exp tests use -w -Wno-psabi
> already).
>
Hm, but this patch violates the ELFv2 ABI as written.  The ABI includes:

"Floating-point and vector aggregates that contain padding words and
integer fields with a width of 0 should not be treated as homogeneous
aggregates."

So if this patch is accepted, it requires an exception in the ABI
document specifically for C++17 empty base fields.  Are these base fields
required by the C++17 specification?  We can't change the ABI just
based on a single implementation if it is not required.  If it is
required, I don't immediately foresee a problem with updating the ABI.

Thanks,
Bill

>
> Bootstrapped/regtested on powerpc64le-linux, bootstrapped on powerpc64-linux
> where regtest is still pending, but homogeneous aggregates are an ELFv2
> thing, so I don't expect it to change anything (and so far no such messages
> appear in the testsuite log files).
>
> Ok for trunk?
>
> 2020-04-22  Jakub Jelinek  <jakub@redhat.com>
>
> 	PR target/94707
> 	* config/rs6000/rs6000-call.c (rs6000_aggregate_candidate): Add
> 	CXX17_EMPTY_BASE_SEEN argument.  Pass it to recursive calls.
> 	Ignore cxx17_empty_base_field_p fields after setting
> 	*CXX17_EMPTY_BASE_SEEN to true.
> 	(rs6000_discover_homogeneous_aggregate): Adjust
> 	rs6000_aggregate_candidate caller.  With -Wpsabi, diagnose homogeneous
> 	aggregates with C++17 empty base fields.
>
> 	* g++.dg/tree-ssa/pr27830.C: Use -Wpsabi -w for -std=c++17 and higher.
>
> --- gcc/config/rs6000/rs6000-call.c.jj	2020-03-30 22:53:40.746640328 +0200
> +++ gcc/config/rs6000/rs6000-call.c	2020-04-22 13:05:07.947809888 +0200
> @@ -5528,7 +5528,8 @@ const struct altivec_builtin_types altiv
>      sub-tree.  */
>   
>   static int
> -rs6000_aggregate_candidate (const_tree type, machine_mode *modep)
> +rs6000_aggregate_candidate (const_tree type, machine_mode *modep,
> +			    bool *cxx17_empty_base_seen)
>   {
>     machine_mode mode;
>     HOST_WIDE_INT size;
> @@ -5598,7 +5599,8 @@ rs6000_aggregate_candidate (const_tree t
>   	    || TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
>   	  return -1;
>   
> -	count = rs6000_aggregate_candidate (TREE_TYPE (type), modep);
> +	count = rs6000_aggregate_candidate (TREE_TYPE (type), modep,
> +					    cxx17_empty_base_seen);
>   	if (count == -1
>   	    || !index
>   	    || !TYPE_MAX_VALUE (index)
> @@ -5636,7 +5638,14 @@ rs6000_aggregate_candidate (const_tree t
>   	    if (TREE_CODE (field) != FIELD_DECL)
>   	      continue;
>   
> -	    sub_count = rs6000_aggregate_candidate (TREE_TYPE (field), modep);
> +	    if (cxx17_empty_base_field_p (field))
> +	      {
> +		*cxx17_empty_base_seen = true;
> +		continue;
> +	      }
> +
> +	    sub_count = rs6000_aggregate_candidate (TREE_TYPE (field), modep,
> +						    cxx17_empty_base_seen);
>   	    if (sub_count < 0)
>   	      return -1;
>   	    count += sub_count;
> @@ -5669,7 +5678,8 @@ rs6000_aggregate_candidate (const_tree t
>   	    if (TREE_CODE (field) != FIELD_DECL)
>   	      continue;
>   
> -	    sub_count = rs6000_aggregate_candidate (TREE_TYPE (field), modep);
> +	    sub_count = rs6000_aggregate_candidate (TREE_TYPE (field), modep,
> +						    cxx17_empty_base_seen);
>   	    if (sub_count < 0)
>   	      return -1;
>   	    count = count > sub_count ? count : sub_count;
> @@ -5710,7 +5720,9 @@ rs6000_discover_homogeneous_aggregate (m
>         && AGGREGATE_TYPE_P (type))
>       {
>         machine_mode field_mode = VOIDmode;
> -      int field_count = rs6000_aggregate_candidate (type, &field_mode);
> +      bool cxx17_empty_base_seen = false;
> +      int field_count = rs6000_aggregate_candidate (type, &field_mode,
> +						    &cxx17_empty_base_seen);
>   
>         if (field_count > 0)
>   	{
> @@ -5725,6 +5737,17 @@ rs6000_discover_homogeneous_aggregate (m
>   		*elt_mode = field_mode;
>   	      if (n_elts)
>   		*n_elts = field_count;
> +	      if (cxx17_empty_base_seen && warn_psabi)
> +		{
> +		  static const_tree last_reported_type;
> +		  if (type != last_reported_type)
> +		    {
> +		      inform (input_location,
> +			      "prior to GCC 10, parameters of type "
> +			      "%qT were passed incorrectly for C++17", type);
> +		      last_reported_type = type;
> +		    }
> +		}
>   	      return true;
>   	    }
>   	}
> --- gcc/testsuite/g++.dg/tree-ssa/pr27830.C.jj	2020-01-11 16:31:54.844296359 +0100
> +++ gcc/testsuite/g++.dg/tree-ssa/pr27830.C	2020-04-22 15:01:37.949881630 +0200
> @@ -1,5 +1,7 @@
>   /* { dg-do compile } */
>   /* { dg-options "-O" } */
> +/* Ignore ABI warnings for C++17 and later.  */
> +/* { dg-additional-options "-Wno-psabi -w" { target c++17 } } */
>   
>   struct gc{};
>   struct transform:public gc
>
> 	Jakub
>
Jakub Jelinek April 22, 2020, 4:49 p.m. UTC | #2
On Wed, Apr 22, 2020 at 11:24:09AM -0500, Bill Schmidt wrote:
> Hm, but this patch violates the ELFv2 ABI as written.  The ABI includes:
> 
> "Floating-point and vector aggregates that contain padding words and
> integer fields with a width of 0 should not be treated as homogeneous
> aggregates."

struct S {};
struct T : public S { float x, y, z; };
doesn't really contain any padding words nor integer fields with a width of
0, it is laid out as x at offset 0, y at offset sizeof (float) and
z at offset sizeof (float) * 2, the struct has sizeof (T) == sizeof (float) * 3.
The ELFv2 ABI certainly can't talk about how GCC implements them and what
TYPE_FIELDS chain elts should be honored and what should be ignored,
it must talk about what is in the source.
struct S {};
struct U { struct S s; float x, y, z; };
in C is considered homogeneous and is laid out exactly the same, and so is
T in C++14, just in C++17 as an implementation detail the C++ FE adds a base
field.
Short description + the patch that introduced it is
https://gcc.gnu.org/legacy-ml/gcc-patches/2016-10/msg01213.html

	Jakub
Li, Pan2 via Gcc-patches April 22, 2020, 4:58 p.m. UTC | #3
On 4/22/20 11:49 AM, Jakub Jelinek wrote:
> On Wed, Apr 22, 2020 at 11:24:09AM -0500, Bill Schmidt wrote:
>> Hm, but this patch violates the ELFv2 ABI as written.  The ABI includes:
>>
>> "Floating-point and vector aggregates that contain padding words and
>> integer fields with a width of 0 should not be treated as homogeneous
>> aggregates."
> struct S {};
> struct T : public S { float x, y, z; };
> doesn't really contain any padding words nor integer fields with a width of
> 0, it is laid out as x at offset 0, y at offset sizeof (float) and
> z at offset sizeof (float) * 2, the struct has sizeof (T) == sizeof (float) * 3.
> The ELFv2 ABI certainly can't talk about how GCC implements them and what
> TYPE_FIELDS chain elts should be honored and what should be ignored,
> it must talk about what is in the source.
> struct S {};
> struct U { struct S s; float x, y, z; };
> in C is considered homogeneous and is laid out exactly the same, and so is
> T in C++14, just in C++17 as an implementation detail the C++ FE adds a base
> field.

OK, on reflection I'll accept that.  Thanks for the explanation.

Bill

> Short description + the patch that introduced it is
> https://gcc.gnu.org/legacy-ml/gcc-patches/2016-10/msg01213.html
>
> 	Jakub
>
Segher Boessenkool April 22, 2020, 10:10 p.m. UTC | #4
Hi!

On Wed, Apr 22, 2020 at 03:11:48PM +0200, Jakub Jelinek wrote:
> The problem is that the presence or absence of the C++17
> artificial empty base fields, which have non-zero TYPE_SIZE, but zero
> DECL_SIZE, change the ABI decisions, if it is present (-std=c++17), the type
> might not be considered homogeneous, while if it is absent (-std=c++14), it
> can be.
> 
> The following patch fixes that and emits a -Wpsabi inform; perhaps more
> often than it could, because the fact that rs6000_discover_homogeneous_aggregate
> returns true when it didn't in in GCC 7/8/9 with -std=c++17 doesn't still
> mean it will make a different ABI decision, but the warning triggered only
> on the test I've changed (the struct-layout-1.exp tests use -w -Wno-psabi
> already).

> 	PR target/94707
> 	* config/rs6000/rs6000-call.c (rs6000_aggregate_candidate): Add
> 	CXX17_EMPTY_BASE_SEEN argument.  Pass it to recursive calls.
> 	Ignore cxx17_empty_base_field_p fields after setting
> 	*CXX17_EMPTY_BASE_SEEN to true.

Please use the literal capitalisation of symbol names?  So that grep and
other search works (the ALL CAPS thing is for the function introductory
comment (and other function comments) only).

> +	    if (cxx17_empty_base_field_p (field))
> +	      {
> +		*cxx17_empty_base_seen = true;
> +		continue;
> +	      }

Is there no way to describe this without referring to "c++17" (or even
"base field")?  It's a pretty gross abstraction violation.

> +		      inform (input_location,
> +			      "prior to GCC 10, parameters of type "
> +			      "%qT were passed incorrectly for C++17", type);

This could more explicitly say that makes the compiled code incompatible
between GCC 10 and older, which is the point of the warning?  It's not
really necessary to say the old one was bad -- let's hope it was :-)

Looks fine otherwise.  Okay for trunk whatever you decide to do (or not
do) with my comments.  Thank you!


Segher
Jakub Jelinek April 23, 2020, 8:06 a.m. UTC | #5
On Wed, Apr 22, 2020 at 05:10:56PM -0500, Segher Boessenkool wrote:
> > 	PR target/94707
> > 	* config/rs6000/rs6000-call.c (rs6000_aggregate_candidate): Add
> > 	CXX17_EMPTY_BASE_SEEN argument.  Pass it to recursive calls.
> > 	Ignore cxx17_empty_base_field_p fields after setting
> > 	*CXX17_EMPTY_BASE_SEEN to true.
> 
> Please use the literal capitalisation of symbol names?  So that grep and
> other search works (the ALL CAPS thing is for the function introductory
> comment (and other function comments) only).

Done.

> > +	    if (cxx17_empty_base_field_p (field))
> > +	      {
> > +		*cxx17_empty_base_seen = true;
> > +		continue;
> > +	      }
> 
> Is there no way to describe this without referring to "c++17" (or even
> "base field")?  It's a pretty gross abstraction violation.

I'm afraid it is desirable to talk about c++17 and base field, otherwise
it won't be clear what we mean.

> > +		      inform (input_location,
> > +			      "prior to GCC 10, parameters of type "
> > +			      "%qT were passed incorrectly for C++17", type);
> 
> This could more explicitly say that makes the compiled code incompatible
> between GCC 10 and older, which is the point of the warning?  It's not
> really necessary to say the old one was bad -- let's hope it was :-)

After many iterations on IRC we came up with the following wording, which is
what I've committed.  Might be nice to also have URL with larger explanation
in changes.html. but the diagnostic framework doesn't support that yet.

2020-04-23  Jakub Jelinek  <jakub@redhat.com>

	PR target/94707
	* config/rs6000/rs6000-call.c (rs6000_aggregate_candidate): Add
	cxx17_empty_base_seen argument.  Pass it to recursive calls.
	Ignore cxx17_empty_base_field_p fields after setting
	*cxx17_empty_base_seen to true.
	(rs6000_discover_homogeneous_aggregate): Adjust
	rs6000_aggregate_candidate caller.  With -Wpsabi, diagnose homogeneous
	aggregates with C++17 empty base fields.

	* g++.dg/tree-ssa/pr27830.C: Use -Wpsabi -w for -std=c++17 and higher.

--- gcc/config/rs6000/rs6000-call.c.jj	2020-03-30 22:53:40.746640328 +0200
+++ gcc/config/rs6000/rs6000-call.c	2020-04-22 13:05:07.947809888 +0200
@@ -5528,7 +5528,8 @@ const struct altivec_builtin_types altiv
    sub-tree.  */
 
 static int
-rs6000_aggregate_candidate (const_tree type, machine_mode *modep)
+rs6000_aggregate_candidate (const_tree type, machine_mode *modep,
+			    bool *cxx17_empty_base_seen)
 {
   machine_mode mode;
   HOST_WIDE_INT size;
@@ -5598,7 +5599,8 @@ rs6000_aggregate_candidate (const_tree t
 	    || TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
 	  return -1;
 
-	count = rs6000_aggregate_candidate (TREE_TYPE (type), modep);
+	count = rs6000_aggregate_candidate (TREE_TYPE (type), modep,
+					    cxx17_empty_base_seen);
 	if (count == -1
 	    || !index
 	    || !TYPE_MAX_VALUE (index)
@@ -5636,7 +5638,14 @@ rs6000_aggregate_candidate (const_tree t
 	    if (TREE_CODE (field) != FIELD_DECL)
 	      continue;
 
-	    sub_count = rs6000_aggregate_candidate (TREE_TYPE (field), modep);
+	    if (cxx17_empty_base_field_p (field))
+	      {
+		*cxx17_empty_base_seen = true;
+		continue;
+	      }
+
+	    sub_count = rs6000_aggregate_candidate (TREE_TYPE (field), modep,
+						    cxx17_empty_base_seen);
 	    if (sub_count < 0)
 	      return -1;
 	    count += sub_count;
@@ -5669,7 +5678,8 @@ rs6000_aggregate_candidate (const_tree t
 	    if (TREE_CODE (field) != FIELD_DECL)
 	      continue;
 
-	    sub_count = rs6000_aggregate_candidate (TREE_TYPE (field), modep);
+	    sub_count = rs6000_aggregate_candidate (TREE_TYPE (field), modep,
+						    cxx17_empty_base_seen);
 	    if (sub_count < 0)
 	      return -1;
 	    count = count > sub_count ? count : sub_count;
@@ -5710,7 +5720,9 @@ rs6000_discover_homogeneous_aggregate (m
       && AGGREGATE_TYPE_P (type))
     {
       machine_mode field_mode = VOIDmode;
-      int field_count = rs6000_aggregate_candidate (type, &field_mode);
+      bool cxx17_empty_base_seen = false;
+      int field_count = rs6000_aggregate_candidate (type, &field_mode,
+						    &cxx17_empty_base_seen);
 
       if (field_count > 0)
 	{
@@ -5725,6 +5737,18 @@ rs6000_discover_homogeneous_aggregate (m
 		*elt_mode = field_mode;
 	      if (n_elts)
 		*n_elts = field_count;
+	      if (cxx17_empty_base_seen && warn_psabi)
+		{
+		  static const_tree last_reported_type;
+		  if (type != last_reported_type)
+		    {
+		      inform (input_location,
+			      "parameter passing for argument of type %qT "
+			      "when C++17 is enabled changed to match C++14 "
+			      "in GCC 10.1", type);
+		      last_reported_type = type;
+		    }
+		}
 	      return true;
 	    }
 	}
--- gcc/testsuite/g++.dg/tree-ssa/pr27830.C.jj	2020-01-11 16:31:54.844296359 +0100
+++ gcc/testsuite/g++.dg/tree-ssa/pr27830.C	2020-04-22 15:01:37.949881630 +0200
@@ -1,5 +1,7 @@
 /* { dg-do compile } */
 /* { dg-options "-O" } */
+/* Ignore ABI warnings for C++17 and later.  */
+/* { dg-additional-options "-Wno-psabi -w" { target c++17 } } */
 
 struct gc{};
 struct transform:public gc


	Jakub
Segher Boessenkool April 23, 2020, 10:24 a.m. UTC | #6
Hi!

On Thu, Apr 23, 2020 at 10:06:16AM +0200, Jakub Jelinek wrote:
> > Is there no way to describe this without referring to "c++17" (or even
> > "base field")?  It's a pretty gross abstraction violation.
> 
> I'm afraid it is desirable to talk about c++17 and base field, otherwise
> it won't be clear what we mean.

Yeah, but that just shows it is a bad abstraction (not an abstraction at
all really, heh).  Not nice :-(

> > > +		      inform (input_location,
> > > +			      "prior to GCC 10, parameters of type "
> > > +			      "%qT were passed incorrectly for C++17", type);
> > 
> > This could more explicitly say that makes the compiled code incompatible
> > between GCC 10 and older, which is the point of the warning?  It's not
> > really necessary to say the old one was bad -- let's hope it was :-)
> 
> After many iterations on IRC we came up with the following wording, which is
> what I've committed.  Might be nice to also have URL with larger explanation
> in changes.html. but the diagnostic framework doesn't support that yet.

> +		      inform (input_location,
> +			      "parameter passing for argument of type %qT "
> +			      "when C++17 is enabled changed to match C++14 "
> +			      "in GCC 10.1", type);

It isn't "to match C++14".  It simply is a bugfix, we didn't follow
the ABI before :-)

Thanks again for doing this work, much appreciated,


Segher
diff mbox series

Patch

--- gcc/config/rs6000/rs6000-call.c.jj	2020-03-30 22:53:40.746640328 +0200
+++ gcc/config/rs6000/rs6000-call.c	2020-04-22 13:05:07.947809888 +0200
@@ -5528,7 +5528,8 @@  const struct altivec_builtin_types altiv
    sub-tree.  */
 
 static int
-rs6000_aggregate_candidate (const_tree type, machine_mode *modep)
+rs6000_aggregate_candidate (const_tree type, machine_mode *modep,
+			    bool *cxx17_empty_base_seen)
 {
   machine_mode mode;
   HOST_WIDE_INT size;
@@ -5598,7 +5599,8 @@  rs6000_aggregate_candidate (const_tree t
 	    || TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
 	  return -1;
 
-	count = rs6000_aggregate_candidate (TREE_TYPE (type), modep);
+	count = rs6000_aggregate_candidate (TREE_TYPE (type), modep,
+					    cxx17_empty_base_seen);
 	if (count == -1
 	    || !index
 	    || !TYPE_MAX_VALUE (index)
@@ -5636,7 +5638,14 @@  rs6000_aggregate_candidate (const_tree t
 	    if (TREE_CODE (field) != FIELD_DECL)
 	      continue;
 
-	    sub_count = rs6000_aggregate_candidate (TREE_TYPE (field), modep);
+	    if (cxx17_empty_base_field_p (field))
+	      {
+		*cxx17_empty_base_seen = true;
+		continue;
+	      }
+
+	    sub_count = rs6000_aggregate_candidate (TREE_TYPE (field), modep,
+						    cxx17_empty_base_seen);
 	    if (sub_count < 0)
 	      return -1;
 	    count += sub_count;
@@ -5669,7 +5678,8 @@  rs6000_aggregate_candidate (const_tree t
 	    if (TREE_CODE (field) != FIELD_DECL)
 	      continue;
 
-	    sub_count = rs6000_aggregate_candidate (TREE_TYPE (field), modep);
+	    sub_count = rs6000_aggregate_candidate (TREE_TYPE (field), modep,
+						    cxx17_empty_base_seen);
 	    if (sub_count < 0)
 	      return -1;
 	    count = count > sub_count ? count : sub_count;
@@ -5710,7 +5720,9 @@  rs6000_discover_homogeneous_aggregate (m
       && AGGREGATE_TYPE_P (type))
     {
       machine_mode field_mode = VOIDmode;
-      int field_count = rs6000_aggregate_candidate (type, &field_mode);
+      bool cxx17_empty_base_seen = false;
+      int field_count = rs6000_aggregate_candidate (type, &field_mode,
+						    &cxx17_empty_base_seen);
 
       if (field_count > 0)
 	{
@@ -5725,6 +5737,17 @@  rs6000_discover_homogeneous_aggregate (m
 		*elt_mode = field_mode;
 	      if (n_elts)
 		*n_elts = field_count;
+	      if (cxx17_empty_base_seen && warn_psabi)
+		{
+		  static const_tree last_reported_type;
+		  if (type != last_reported_type)
+		    {
+		      inform (input_location,
+			      "prior to GCC 10, parameters of type "
+			      "%qT were passed incorrectly for C++17", type);
+		      last_reported_type = type;
+		    }
+		}
 	      return true;
 	    }
 	}
--- gcc/testsuite/g++.dg/tree-ssa/pr27830.C.jj	2020-01-11 16:31:54.844296359 +0100
+++ gcc/testsuite/g++.dg/tree-ssa/pr27830.C	2020-04-22 15:01:37.949881630 +0200
@@ -1,5 +1,7 @@ 
 /* { dg-do compile } */
 /* { dg-options "-O" } */
+/* Ignore ABI warnings for C++17 and later.  */
+/* { dg-additional-options "-Wno-psabi -w" { target c++17 } } */
 
 struct gc{};
 struct transform:public gc