Fix TYPE_EMPTY_P handling - x86_64 ABI issue (PR target/84502)

Message ID 20180221223720.GT5867@tucnak
State New
Headers show
Series
  • Fix TYPE_EMPTY_P handling - x86_64 ABI issue (PR target/84502)
Related show

Commit Message

Jakub Jelinek Feb. 21, 2018, 10:37 p.m.
Hi!

The following testcase shows that we set TYPE_EMPTY_P just one of the
possibly many variants of an aggregate type.
On the testcase, in one case (in the callee) we check TYPE_EMPTY_P on X which is
the type variant for the using type, and in another case we check it on the
A<int> type instead, which has TYPE_EMPTY_P set.

Bootstrap/regtest pending on x86_64-linux and i686-linux, ok if it passes?

2018-02-21  Jakub Jelinek  <jakub@redhat.com>

	PR target/84502
	* stor-layout.c (finalize_type_size): Propagate TYPE_EMPTY_P flag
	to all type variants.

	* g++.dg/torture/pr84502.C: New test.


	Jakub

Comments

Richard Biener Feb. 22, 2018, 7:40 a.m. | #1
On February 21, 2018 11:37:20 PM GMT+01:00, Jakub Jelinek <jakub@redhat.com> wrote:
>Hi!

>

>The following testcase shows that we set TYPE_EMPTY_P just one of the

>possibly many variants of an aggregate type.

>On the testcase, in one case (in the callee) we check TYPE_EMPTY_P on X

>which is

>the type variant for the using type, and in another case we check it on

>the

>A<int> type instead, which has TYPE_EMPTY_P set.

>

>Bootstrap/regtest pending on x86_64-linux and i686-linux, ok if it

>passes?


OK. 

Richard. 

>2018-02-21  Jakub Jelinek  <jakub@redhat.com>

>

>	PR target/84502

>	* stor-layout.c (finalize_type_size): Propagate TYPE_EMPTY_P flag

>	to all type variants.

>

>	* g++.dg/torture/pr84502.C: New test.

>

>--- gcc/stor-layout.c.jj	2018-02-13 21:23:29.187981310 +0100

>+++ gcc/stor-layout.c	2018-02-21 21:43:24.783522853 +0100

>@@ -1883,6 +1883,9 @@ finalize_type_size (tree type)

>       && TREE_CODE (TYPE_SIZE_UNIT (type)) != INTEGER_CST)

>     TYPE_SIZE_UNIT (type) = variable_size (TYPE_SIZE_UNIT (type));

> 

>+  /* Handle empty records as per the x86-64 psABI.  */

>+  TYPE_EMPTY_P (type) = targetm.calls.empty_record_p (type);

>+

>   /* Also layout any other variants of the type.  */

>   if (TYPE_NEXT_VARIANT (type)

>       || type != TYPE_MAIN_VARIANT (type))

>@@ -1895,6 +1898,7 @@ finalize_type_size (tree type)

>       unsigned int precision = TYPE_PRECISION (type);

>       unsigned int user_align = TYPE_USER_ALIGN (type);

>       machine_mode mode = TYPE_MODE (type);

>+      bool empty_p = TYPE_EMPTY_P (type);

> 

>       /* Copy it into all variants.  */

>       for (variant = TYPE_MAIN_VARIANT (type);

>@@ -1911,11 +1915,9 @@ finalize_type_size (tree type)

> 	  SET_TYPE_ALIGN (variant, valign);

> 	  TYPE_PRECISION (variant) = precision;

> 	  SET_TYPE_MODE (variant, mode);

>+	  TYPE_EMPTY_P (variant) = empty_p;

> 	}

>     }

>-

>-  /* Handle empty records as per the x86-64 psABI.  */

>-  TYPE_EMPTY_P (type) = targetm.calls.empty_record_p (type);

> }

> 

>/* Return a new underlying object for a bitfield started with FIELD. 

>*/

>--- gcc/testsuite/g++.dg/torture/pr84502.C.jj	2018-02-21

>22:13:22.279420017 +0100

>+++ gcc/testsuite/g++.dg/torture/pr84502.C	2018-02-21

>22:13:03.727424362 +0100

>@@ -0,0 +1,20 @@

>+// PR target/84502

>+// { dg-do run }

>+

>+template<typename T>

>+struct A { };

>+using X = A<int>;

>+

>+void

>+foo (X, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int

>a8)

>+{

>+  if (a1 != 0 || a2 != 1 || a3 != 2 || a4 != 3

>+      || a5 != 4 || a6 != 5 || a7 != 6 || a8 != 7)

>+    __builtin_abort ();

>+}

>+

>+int

>+main ()

>+{

>+  foo (X{}, 0, 1, 2, 3, 4, 5, 6, 7);

>+}

>

>	Jakub

Patch

--- gcc/stor-layout.c.jj	2018-02-13 21:23:29.187981310 +0100
+++ gcc/stor-layout.c	2018-02-21 21:43:24.783522853 +0100
@@ -1883,6 +1883,9 @@  finalize_type_size (tree type)
       && TREE_CODE (TYPE_SIZE_UNIT (type)) != INTEGER_CST)
     TYPE_SIZE_UNIT (type) = variable_size (TYPE_SIZE_UNIT (type));
 
+  /* Handle empty records as per the x86-64 psABI.  */
+  TYPE_EMPTY_P (type) = targetm.calls.empty_record_p (type);
+
   /* Also layout any other variants of the type.  */
   if (TYPE_NEXT_VARIANT (type)
       || type != TYPE_MAIN_VARIANT (type))
@@ -1895,6 +1898,7 @@  finalize_type_size (tree type)
       unsigned int precision = TYPE_PRECISION (type);
       unsigned int user_align = TYPE_USER_ALIGN (type);
       machine_mode mode = TYPE_MODE (type);
+      bool empty_p = TYPE_EMPTY_P (type);
 
       /* Copy it into all variants.  */
       for (variant = TYPE_MAIN_VARIANT (type);
@@ -1911,11 +1915,9 @@  finalize_type_size (tree type)
 	  SET_TYPE_ALIGN (variant, valign);
 	  TYPE_PRECISION (variant) = precision;
 	  SET_TYPE_MODE (variant, mode);
+	  TYPE_EMPTY_P (variant) = empty_p;
 	}
     }
-
-  /* Handle empty records as per the x86-64 psABI.  */
-  TYPE_EMPTY_P (type) = targetm.calls.empty_record_p (type);
 }
 
 /* Return a new underlying object for a bitfield started with FIELD.  */
--- gcc/testsuite/g++.dg/torture/pr84502.C.jj	2018-02-21 22:13:22.279420017 +0100
+++ gcc/testsuite/g++.dg/torture/pr84502.C	2018-02-21 22:13:03.727424362 +0100
@@ -0,0 +1,20 @@ 
+// PR target/84502
+// { dg-do run }
+
+template<typename T>
+struct A { };
+using X = A<int>;
+
+void
+foo (X, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8)
+{
+  if (a1 != 0 || a2 != 1 || a3 != 2 || a4 != 3
+      || a5 != 4 || a6 != 5 || a7 != 6 || a8 != 7)
+    __builtin_abort ();
+}
+
+int
+main ()
+{
+  foo (X{}, 0, 1, 2, 3, 4, 5, 6, 7);
+}