aboutsummaryrefslogtreecommitdiff
path: root/gcc/testsuite/g++.dg/cpp23
diff options
context:
space:
mode:
authorPatrick Palka <ppalka@redhat.com>2024-08-09 21:15:25 -0400
committerPatrick Palka <ppalka@redhat.com>2024-08-09 21:15:25 -0400
commit8cc67b520968ca9a13fd96896522aa66e39a99e2 (patch)
tree9e37bbf8d78bc0b57f6cd2cbb14dbc122ae8fdd9 /gcc/testsuite/g++.dg/cpp23
parent70da0ca1239faefa6dec0494a85e998eae34beff (diff)
downloadgcc-8cc67b520968ca9a13fd96896522aa66e39a99e2.zip
gcc-8cc67b520968ca9a13fd96896522aa66e39a99e2.tar.gz
gcc-8cc67b520968ca9a13fd96896522aa66e39a99e2.tar.bz2
c++: inherited CTAD fixes [PR116276]
This implements the overlooked inherited vs non-inherited guide tiebreaker from P2582R1. This requires tracking inherited-ness of a guide, for which it seems natural to reuse the lang_decl_fn::context field which for a constructor tracks its inherited-ness. This patch also works around CLASSTYPE_CONSTRUCTORS not reliably returning all inherited constructors (due to some using-decl handling quirks in in push_class_level_binding) by iterating over TYPE_FIELDS instead. This patch also makes us recognize another written form of inherited constructor, 'using Base<T>::Base::Base' whose USING_DECL_SCOPE is a TYPENAME_TYPE. PR c++/116276 gcc/cp/ChangeLog: * call.cc (joust): Implement P2582R1 inherited vs non-inherited guide tiebreaker. * cp-tree.h (lang_decl_fn::context): Document usage in deduction_guide_p FUNCTION_DECLs. (inherited_guide_p): Declare. * pt.cc (inherited_guide_p): Define. (set_inherited_guide_context): Define. (alias_ctad_tweaks): Use set_inherited_guide_context. (inherited_ctad_tweaks): Recognize some inherited constructors whose scope is a TYPENAME_TYPE. (ctor_deduction_guides_for): For C++23 inherited CTAD, iterate over TYPE_FIELDS instead of CLASSTYPE_CONSTRUCTORS to recognize all inherited constructors. gcc/testsuite/ChangeLog: * g++.dg/cpp23/class-deduction-inherited4.C: Remove an xfail. * g++.dg/cpp23/class-deduction-inherited5.C: New test. * g++.dg/cpp23/class-deduction-inherited6.C: New test. Reviewed-by: Jason Merrill <jason@redhat.com>
Diffstat (limited to 'gcc/testsuite/g++.dg/cpp23')
-rw-r--r--gcc/testsuite/g++.dg/cpp23/class-deduction-inherited4.C4
-rw-r--r--gcc/testsuite/g++.dg/cpp23/class-deduction-inherited5.C25
-rw-r--r--gcc/testsuite/g++.dg/cpp23/class-deduction-inherited6.C46
3 files changed, 73 insertions, 2 deletions
diff --git a/gcc/testsuite/g++.dg/cpp23/class-deduction-inherited4.C b/gcc/testsuite/g++.dg/cpp23/class-deduction-inherited4.C
index 5e3a7f4..806f016 100644
--- a/gcc/testsuite/g++.dg/cpp23/class-deduction-inherited4.C
+++ b/gcc/testsuite/g++.dg/cpp23/class-deduction-inherited4.C
@@ -13,10 +13,10 @@ using ty1 = B<int>;
template<class T=void>
struct C : A<int> {
- using A<int>::A; // FIXME: we don't notice this one either
+ using A<int>::A;
};
-using ty2 = decltype(C(0)); // { dg-bogus "" "" { xfail *-*-* } }
+using ty2 = decltype(C(0));
using ty2 = C<void>;
template<class T>
diff --git a/gcc/testsuite/g++.dg/cpp23/class-deduction-inherited5.C b/gcc/testsuite/g++.dg/cpp23/class-deduction-inherited5.C
new file mode 100644
index 0000000..d835acb
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp23/class-deduction-inherited5.C
@@ -0,0 +1,25 @@
+// PR c++/116276
+// { dg-do compile { target c++20 } }
+
+template<class T>
+struct Base1 { };
+
+template<class T>
+struct Base2 { };
+
+template<class T = int>
+struct Derived : public Base1<T>, Base2<T> {
+ using Base1<T>::Base1;
+ using Base2<T>::Base2;
+};
+
+Derived d;
+
+template<class T = int>
+struct Derived2 : public Base1<T>, Base2<T> {
+ using Base1<T>::Base1::Base1;
+ using Base2<T>::Base2::Base2;
+ Derived2();
+};
+
+Derived2 d2;
diff --git a/gcc/testsuite/g++.dg/cpp23/class-deduction-inherited6.C b/gcc/testsuite/g++.dg/cpp23/class-deduction-inherited6.C
new file mode 100644
index 0000000..df8199c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp23/class-deduction-inherited6.C
@@ -0,0 +1,46 @@
+// PR c++/116276
+// { dg-do compile { target c++23 } }
+
+template<class T>
+struct Base1 {
+ Base1();
+ Base1(T);
+};
+
+template<class T>
+struct Base2 {
+ Base2();
+ Base2(T*);
+};
+
+template<class T = int>
+struct Derived : public Base1<T>, Base2<T> {
+ using Base1<T>::Base1;
+ using Base2<T>::Base2;
+};
+
+using ty1 = decltype(Derived{});
+using ty1 = Derived<int>;
+
+using ty2 = decltype(Derived{true});
+using ty2 = Derived<bool>;
+
+using ty3 = decltype(Derived{(char*)nullptr});
+using ty3 = Derived<char>;
+
+template<class T = int>
+struct Derived2 : public Base1<T>, Base2<T> {
+ using Base1<T>::Base1;
+ using Base2<T>::Base2;
+ Derived2();
+ Derived2(T);
+};
+
+using ty4 = decltype(Derived2{});
+using ty4 = Derived2<int>;
+
+using ty5 = decltype(Derived2{true});
+using ty5 = Derived2<bool>;
+
+using ty6 = decltype(Derived2{(char*)nullptr});
+using ty6 = Derived2<char>;