diff options
author | Nathaniel Shead <nathanieloshead@gmail.com> | 2024-08-08 17:52:03 +1000 |
---|---|---|
committer | Nathaniel Shead <nathanieloshead@gmail.com> | 2024-08-08 22:42:13 +1000 |
commit | 71aebb36174c194231da5f9c7c23f81dbb082ca4 (patch) | |
tree | be684b6d4d9c599980569c75db75b4cf663ea0a2 | |
parent | 0de1481a9d91e936135da4f882314499eea38a36 (diff) | |
download | gcc-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>
-rw-r--r-- | gcc/cp/class.cc | 31 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/modules/pr115062_a.H | 6 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/modules/pr115062_b.H | 14 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/modules/pr115062_c.C | 9 |
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() + ""; +} |