diff mbox series

c++: Propagate TREE_ADDRESSABLE in fixup_type_variants [PR115062]

Message ID 66b4b327.170a0220.27dd28.60ca@mx.google.com
State New
Headers show
Series c++: Propagate TREE_ADDRESSABLE in fixup_type_variants [PR115062] | expand

Commit Message

Nathaniel Shead Aug. 8, 2024, 11:59 a.m. UTC
Bootstrapped and regtested on x86_64-pc-linux-gnu, OK for trunk?

The change to 'finish_struct_bits' is not required for this PR but I
felt it was a nice cleanup; happy to commit without it though if
preferred.

-- >8 --

This has caused issues with modules when an import fills in the
definition of a type already created with a typedef.

	PR c++/115062

gcc/cp/ChangeLog:

	* class.cc (fixup_type_variants): Propagate TREE_ADDRESSABLE.
	(finish_struct_bits): Cleanup now that TREE_ADDRESSABLE is
	propagated by fixup_type_variants.

gcc/testsuite/ChangeLog:

	* g++.dg/modules/pr115062_a.H: New test.
	* g++.dg/modules/pr115062_b.H: New test.
	* g++.dg/modules/pr115062_c.C: New test.

Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com>
---
 gcc/cp/class.cc                           | 31 ++++++++++-------------
 gcc/testsuite/g++.dg/modules/pr115062_a.H |  6 +++++
 gcc/testsuite/g++.dg/modules/pr115062_b.H | 14 ++++++++++
 gcc/testsuite/g++.dg/modules/pr115062_c.C |  9 +++++++
 4 files changed, 43 insertions(+), 17 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/modules/pr115062_a.H
 create mode 100644 gcc/testsuite/g++.dg/modules/pr115062_b.H
 create mode 100644 gcc/testsuite/g++.dg/modules/pr115062_c.C

Comments

Jason Merrill Aug. 8, 2024, 12:39 p.m. UTC | #1
On 8/8/24 7:59 AM, Nathaniel Shead wrote:
> Bootstrapped and regtested on x86_64-pc-linux-gnu, OK for trunk?

OK.

> The change to 'finish_struct_bits' is not required for this PR but I
> felt it was a nice cleanup; happy to commit without it though if
> preferred.
> 
> -- >8 --
> 
> This has caused issues with modules when an import fills in the
> definition of a type already created with a typedef.
> 
> 	PR c++/115062
> 
> gcc/cp/ChangeLog:
> 
> 	* class.cc (fixup_type_variants): Propagate TREE_ADDRESSABLE.
> 	(finish_struct_bits): Cleanup now that TREE_ADDRESSABLE is
> 	propagated by fixup_type_variants.
> 
> gcc/testsuite/ChangeLog:
> 
> 	* g++.dg/modules/pr115062_a.H: New test.
> 	* g++.dg/modules/pr115062_b.H: New test.
> 	* g++.dg/modules/pr115062_c.C: New test.
> 
> Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com>
> ---
>   gcc/cp/class.cc                           | 31 ++++++++++-------------
>   gcc/testsuite/g++.dg/modules/pr115062_a.H |  6 +++++
>   gcc/testsuite/g++.dg/modules/pr115062_b.H | 14 ++++++++++
>   gcc/testsuite/g++.dg/modules/pr115062_c.C |  9 +++++++
>   4 files changed, 43 insertions(+), 17 deletions(-)
>   create mode 100644 gcc/testsuite/g++.dg/modules/pr115062_a.H
>   create mode 100644 gcc/testsuite/g++.dg/modules/pr115062_b.H
>   create mode 100644 gcc/testsuite/g++.dg/modules/pr115062_c.C
> 
> diff --git a/gcc/cp/class.cc b/gcc/cp/class.cc
> index 718601756dd..fb6c3370950 100644
> --- a/gcc/cp/class.cc
> +++ b/gcc/cp/class.cc
> @@ -2312,6 +2312,7 @@ fixup_type_variants (tree type)
>         TYPE_PRECISION (variant) = TYPE_PRECISION (type);
>         TYPE_MODE_RAW (variant) = TYPE_MODE_RAW (type);
>         TYPE_EMPTY_P (variant) = TYPE_EMPTY_P (type);
> +      TREE_ADDRESSABLE (variant) = TREE_ADDRESSABLE (type);
>       }
>   }
>   
> @@ -2378,8 +2379,17 @@ fixup_attribute_variants (tree t)
>   static void
>   finish_struct_bits (tree t)
>   {
> -  /* Fix up variants (if any).  */
> -  fixup_type_variants (t);
> +  /* If this type has a copy constructor or a destructor, force its
> +     mode to be BLKmode, and force its TREE_ADDRESSABLE bit to be
> +     nonzero.  This will cause it to be passed by invisible reference
> +     and prevent it from being returned in a register.  */
> +  if (type_has_nontrivial_copy_init (t)
> +      || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t))
> +    {
> +      SET_DECL_MODE (TYPE_MAIN_DECL (t), BLKmode);
> +      SET_TYPE_MODE (t, BLKmode);
> +      TREE_ADDRESSABLE (t) = 1;
> +    }
>   
>     if (BINFO_N_BASE_BINFOS (TYPE_BINFO (t)) && TYPE_POLYMORPHIC_P (t))
>       /* For a class w/o baseclasses, 'finish_struct' has set
> @@ -2392,21 +2402,8 @@ finish_struct_bits (tree t)
>          looking in the vtables).  */
>       get_pure_virtuals (t);
>   
> -  /* If this type has a copy constructor or a destructor, force its
> -     mode to be BLKmode, and force its TREE_ADDRESSABLE bit to be
> -     nonzero.  This will cause it to be passed by invisible reference
> -     and prevent it from being returned in a register.  */
> -  if (type_has_nontrivial_copy_init (t)
> -      || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t))
> -    {
> -      tree variants;
> -      SET_DECL_MODE (TYPE_MAIN_DECL (t), BLKmode);
> -      for (variants = t; variants; variants = TYPE_NEXT_VARIANT (variants))
> -	{
> -	  SET_TYPE_MODE (variants, BLKmode);
> -	  TREE_ADDRESSABLE (variants) = 1;
> -	}
> -    }
> +  /* Fix up variants (if any).  */
> +  fixup_type_variants (t);
>   }
>   
>   /* Issue warnings about T having private constructors, but no friends,
> diff --git a/gcc/testsuite/g++.dg/modules/pr115062_a.H b/gcc/testsuite/g++.dg/modules/pr115062_a.H
> new file mode 100644
> index 00000000000..3c9daac317e
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/modules/pr115062_a.H
> @@ -0,0 +1,6 @@
> +// PR c++/115062
> +// { dg-additional-options "-fmodule-header" }
> +// { dg-module-cmi {} }
> +
> +template <typename T> class S;
> +typedef S<char> X;
> diff --git a/gcc/testsuite/g++.dg/modules/pr115062_b.H b/gcc/testsuite/g++.dg/modules/pr115062_b.H
> new file mode 100644
> index 00000000000..d8da59591ec
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/modules/pr115062_b.H
> @@ -0,0 +1,14 @@
> +// PR c++/115062
> +// { dg-additional-options "-fmodule-header" }
> +// { dg-module-cmi {} }
> +
> +template <typename>
> +struct S {
> +  int a;
> +  long b;
> +  union {};
> +  ~S();
> +  void foo();
> +};
> +extern template void S<char>::foo();
> +S<char> operator+(S<char>, const char *);
> diff --git a/gcc/testsuite/g++.dg/modules/pr115062_c.C b/gcc/testsuite/g++.dg/modules/pr115062_c.C
> new file mode 100644
> index 00000000000..5255b9ffca7
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/modules/pr115062_c.C
> @@ -0,0 +1,9 @@
> +// PR c++/115062
> +// { dg-additional-options "-fmodules-ts" }
> +
> +import "pr115062_a.H";
> +import "pr115062_b.H";
> +
> +int main() {
> +  X x = X() + "";
> +}
diff mbox series

Patch

diff --git a/gcc/cp/class.cc b/gcc/cp/class.cc
index 718601756dd..fb6c3370950 100644
--- a/gcc/cp/class.cc
+++ b/gcc/cp/class.cc
@@ -2312,6 +2312,7 @@  fixup_type_variants (tree type)
       TYPE_PRECISION (variant) = TYPE_PRECISION (type);
       TYPE_MODE_RAW (variant) = TYPE_MODE_RAW (type);
       TYPE_EMPTY_P (variant) = TYPE_EMPTY_P (type);
+      TREE_ADDRESSABLE (variant) = TREE_ADDRESSABLE (type);
     }
 }
 
@@ -2378,8 +2379,17 @@  fixup_attribute_variants (tree t)
 static void
 finish_struct_bits (tree t)
 {
-  /* Fix up variants (if any).  */
-  fixup_type_variants (t);
+  /* If this type has a copy constructor or a destructor, force its
+     mode to be BLKmode, and force its TREE_ADDRESSABLE bit to be
+     nonzero.  This will cause it to be passed by invisible reference
+     and prevent it from being returned in a register.  */
+  if (type_has_nontrivial_copy_init (t)
+      || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t))
+    {
+      SET_DECL_MODE (TYPE_MAIN_DECL (t), BLKmode);
+      SET_TYPE_MODE (t, BLKmode);
+      TREE_ADDRESSABLE (t) = 1;
+    }
 
   if (BINFO_N_BASE_BINFOS (TYPE_BINFO (t)) && TYPE_POLYMORPHIC_P (t))
     /* For a class w/o baseclasses, 'finish_struct' has set
@@ -2392,21 +2402,8 @@  finish_struct_bits (tree t)
        looking in the vtables).  */
     get_pure_virtuals (t);
 
-  /* If this type has a copy constructor or a destructor, force its
-     mode to be BLKmode, and force its TREE_ADDRESSABLE bit to be
-     nonzero.  This will cause it to be passed by invisible reference
-     and prevent it from being returned in a register.  */
-  if (type_has_nontrivial_copy_init (t)
-      || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t))
-    {
-      tree variants;
-      SET_DECL_MODE (TYPE_MAIN_DECL (t), BLKmode);
-      for (variants = t; variants; variants = TYPE_NEXT_VARIANT (variants))
-	{
-	  SET_TYPE_MODE (variants, BLKmode);
-	  TREE_ADDRESSABLE (variants) = 1;
-	}
-    }
+  /* Fix up variants (if any).  */
+  fixup_type_variants (t);
 }
 
 /* Issue warnings about T having private constructors, but no friends,
diff --git a/gcc/testsuite/g++.dg/modules/pr115062_a.H b/gcc/testsuite/g++.dg/modules/pr115062_a.H
new file mode 100644
index 00000000000..3c9daac317e
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/pr115062_a.H
@@ -0,0 +1,6 @@ 
+// PR c++/115062
+// { dg-additional-options "-fmodule-header" }
+// { dg-module-cmi {} }
+
+template <typename T> class S;
+typedef S<char> X;
diff --git a/gcc/testsuite/g++.dg/modules/pr115062_b.H b/gcc/testsuite/g++.dg/modules/pr115062_b.H
new file mode 100644
index 00000000000..d8da59591ec
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/pr115062_b.H
@@ -0,0 +1,14 @@ 
+// PR c++/115062
+// { dg-additional-options "-fmodule-header" }
+// { dg-module-cmi {} }
+
+template <typename>
+struct S {
+  int a;
+  long b;
+  union {};
+  ~S();
+  void foo();
+};
+extern template void S<char>::foo();
+S<char> operator+(S<char>, const char *);
diff --git a/gcc/testsuite/g++.dg/modules/pr115062_c.C b/gcc/testsuite/g++.dg/modules/pr115062_c.C
new file mode 100644
index 00000000000..5255b9ffca7
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/pr115062_c.C
@@ -0,0 +1,9 @@ 
+// PR c++/115062
+// { dg-additional-options "-fmodules-ts" }
+
+import "pr115062_a.H";
+import "pr115062_b.H";
+
+int main() {
+  X x = X() + "";
+}