aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2022-04-04 11:56:38 -0400
committerJason Merrill <jason@redhat.com>2022-04-05 12:29:33 -0400
commit5d583d24200ac33a1cb281b7ddee9aad351151b5 (patch)
tree1cfc2dfb4e7a0fffc6c757a414a607705c266a0a /gcc
parent1de6612d994ada8edaab18bbc6afd8e9a57413aa (diff)
downloadgcc-5d583d24200ac33a1cb281b7ddee9aad351151b5.zip
gcc-5d583d24200ac33a1cb281b7ddee9aad351151b5.tar.gz
gcc-5d583d24200ac33a1cb281b7ddee9aad351151b5.tar.bz2
c++: alias template equivalence and CTAD [PR103852]
I had been thinking about DR1286 "equivalence" as meaning generally interchangeable, but looking back at the proposed resolution in the context of this PR, I see that it's just about use as a template argument. So let's give a pedwarn if we look through a renaming alias. PR c++/103852 DR 1286 gcc/cp/ChangeLog: * pt.cc (do_class_deduction): Pedwarn for renaming alias in C++17. gcc/testsuite/ChangeLog: * g++.dg/cpp1z/class-deduction-alias1.C: Expect warning.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/pt.cc26
-rw-r--r--gcc/testsuite/g++.dg/cpp1z/class-deduction-alias1.C3
2 files changed, 23 insertions, 6 deletions
diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index 1f0231f..eeebc4c 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -29909,8 +29909,6 @@ do_class_deduction (tree ptype, tree tmpl, tree init,
&& CLASS_PLACEHOLDER_TEMPLATE (TREE_TYPE (init)) == tmpl)
return cp_build_qualified_type (TREE_TYPE (init), cp_type_quals (ptype));
- /* Look through alias templates that just rename another template. */
- tmpl = get_underlying_template (tmpl);
if (!ctad_template_p (tmpl))
{
if (complain & tf_error)
@@ -29920,15 +29918,33 @@ do_class_deduction (tree ptype, tree tmpl, tree init,
else if (cxx_dialect < cxx20 && DECL_ALIAS_TEMPLATE_P (tmpl))
{
if (complain & tf_error)
- error ("alias template deduction only available "
- "with %<-std=c++20%> or %<-std=gnu++20%>");
- return error_mark_node;
+ {
+ /* Be permissive with equivalent alias templates. */
+ tree u = get_underlying_template (tmpl);
+ diagnostic_t dk = (u == tmpl) ? DK_ERROR : DK_PEDWARN;
+ bool complained
+ = emit_diagnostic (dk, input_location, 0,
+ "alias template deduction only available "
+ "with %<-std=c++20%> or %<-std=gnu++20%>");
+ if (u == tmpl)
+ return error_mark_node;
+ else if (complained)
+ {
+ inform (input_location, "use %qD directly instead", u);
+ tmpl = u;
+ }
+ }
+ else
+ return error_mark_node;
}
/* Wait until the initializer is non-dependent. */
if (type_dependent_expression_p (init))
return ptype;
+ /* Don't bother with the alias rules for an equivalent template. */
+ tmpl = get_underlying_template (tmpl);
+
tree type = TREE_TYPE (tmpl);
bool try_list_ctor = false;
diff --git a/gcc/testsuite/g++.dg/cpp1z/class-deduction-alias1.C b/gcc/testsuite/g++.dg/cpp1z/class-deduction-alias1.C
index 1ec90b5..ffa5f2b 100644
--- a/gcc/testsuite/g++.dg/cpp1z/class-deduction-alias1.C
+++ b/gcc/testsuite/g++.dg/cpp1z/class-deduction-alias1.C
@@ -1,5 +1,6 @@
// PR c++/103852
// { dg-do compile { target c++17 } }
+// { dg-options "" }
template <class T> struct b{};
template <class T, class T1 = b<T>>
@@ -10,7 +11,7 @@ struct s
s c(100);
template <class T, class T1 = b<T>>
using ss = s<T, T1>; // equivalent under proposed resolution of DR 1286
-ss tt(1); // OK
+ss tt(1); // { dg-warning "alias template deduction" "" { target c++17_only } }
template <class T, class T1 = T>
using ss2 = s<T, T1>; // different default arg makes it non-equivalent