From 71aebb36174c194231da5f9c7c23f81dbb082ca4 Mon Sep 17 00:00:00 2001 From: Nathaniel Shead <nathanieloshead@gmail.com> Date: Thu, 8 Aug 2024 17:52:03 +1000 Subject: [PATCH] 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> --- 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 718601756ddc..fb6c33709500 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 000000000000..3c9daac317e6 --- /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 000000000000..d8da59591ec5 --- /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 000000000000..5255b9ffca7a --- /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() + ""; +} -- GitLab