aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorNathaniel Shead <nathanieloshead@gmail.com>2024-08-08 17:52:03 +1000
committerNathaniel Shead <nathanieloshead@gmail.com>2024-08-08 22:42:13 +1000
commit71aebb36174c194231da5f9c7c23f81dbb082ca4 (patch)
treebe684b6d4d9c599980569c75db75b4cf663ea0a2 /gcc
parent0de1481a9d91e936135da4f882314499eea38a36 (diff)
downloadgcc-71aebb36174c194231da5f9c7c23f81dbb082ca4.zip
gcc-71aebb36174c194231da5f9c7c23f81dbb082ca4.tar.gz
gcc-71aebb36174c194231da5f9c7c23f81dbb082ca4.tar.bz2
c++: Propagate TREE_ADDRESSABLE in fixup_type_variants [PR115062]
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>
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/class.cc31
-rw-r--r--gcc/testsuite/g++.dg/modules/pr115062_a.H6
-rw-r--r--gcc/testsuite/g++.dg/modules/pr115062_b.H14
-rw-r--r--gcc/testsuite/g++.dg/modules/pr115062_c.C9
4 files changed, 43 insertions, 17 deletions
diff --git a/gcc/cp/class.cc b/gcc/cp/class.cc
index 7186017..fb6c337 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 0000000..3c9daac
--- /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 0000000..d8da595
--- /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 0000000..5255b9f
--- /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() + "";
+}