Message ID | 66b4b327.170a0220.27dd28.60ca@mx.google.com |
---|---|
State | New |
Headers | show |
Series | c++: Propagate TREE_ADDRESSABLE in fixup_type_variants [PR115062] | expand |
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 --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() + ""; +}
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