aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2022-04-27 11:13:24 -0400
committerJason Merrill <jason@redhat.com>2022-04-29 17:24:27 -0400
commit4259c229b457361a9b5cdec157e058bf0c2c8b77 (patch)
treeb5b991c4bb1f2021423c93d57b8dbed42fdb5b27 /gcc
parent53e7252140c95afc859ade521a61ab4115d7fb11 (diff)
downloadgcc-4259c229b457361a9b5cdec157e058bf0c2c8b77.zip
gcc-4259c229b457361a9b5cdec157e058bf0c2c8b77.tar.gz
gcc-4259c229b457361a9b5cdec157e058bf0c2c8b77.tar.bz2
c++: alias CTAD and member alias templates [PR104470]
In this testcase, we were trying to substitute into variant<Foo<T>>::__accepted_type, but failed to look it up because variant<Foo<T>> doesn't exist. In other cases we already rewrite such things into a dependent reference; we need to do that for alias templates as well. This caused some testsuite regressions on alias uses outside of deduction guides, so I've made all of this rewriting conditional on a new tf_dguide tsubst flag. PR c++/104470 gcc/cp/ChangeLog: * cp-tree.h (enum tsubst_flags): Add tf_dguide. * pt.cc (tsubst_aggr_type): Check it. (tsubst_baselink, tsubst_copy): Check it. (maybe_dependent_member_ref): Check it. (instantiate_alias_template): Handle it. (build_deduction_guide): Set it. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/explicit11.C: Second example also ill-formed. * g++.dg/cpp2a/class-deduction-alias12.C: New test.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/cp-tree.h1
-rw-r--r--gcc/cp/pt.cc27
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/class-deduction-alias12.C23
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/explicit11.C2
4 files changed, 47 insertions, 6 deletions
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index e9a3d09..7217799 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -5565,6 +5565,7 @@ enum tsubst_flags {
constraint normalization. */
tf_tst_ok = 1 << 12, /* Allow a typename-specifier to name
a template (C++17 or later). */
+ tf_dguide = 1 << 13, /* Building a deduction guide from a ctor. */
/* Convenient substitution flags combinations. */
tf_warning_or_error = tf_warning | tf_error
};
diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index 81f7ef5..81c3c59 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -13730,8 +13730,8 @@ tsubst_aggr_type (tree t,
complain, in_decl);
if (argvec == error_mark_node)
r = error_mark_node;
- else if (!entering_scope
- && cxx_dialect >= cxx17 && dependent_scope_p (context))
+ else if (!entering_scope && (complain & tf_dguide)
+ && dependent_scope_p (context))
{
/* See maybe_dependent_member_ref. */
tree name = TYPE_IDENTIFIER (t);
@@ -16497,7 +16497,7 @@ tsubst_baselink (tree baselink, tree object_type,
name = make_conv_op_name (optype);
/* See maybe_dependent_member_ref. */
- if (dependent_scope_p (qualifying_scope))
+ if ((complain & tf_dguide) && dependent_scope_p (qualifying_scope))
{
if (template_id_p)
name = build2 (TEMPLATE_ID_EXPR, unknown_type_node, name,
@@ -16817,7 +16817,7 @@ static tree
maybe_dependent_member_ref (tree t, tree args, tsubst_flags_t complain,
tree in_decl)
{
- if (cxx_dialect < cxx17)
+ if (!(complain & tf_dguide))
return NULL_TREE;
tree ctx = context_for_name_lookup (t);
@@ -17075,7 +17075,7 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
have to substitute this with one having context `D<int>'. */
tree context = tsubst (DECL_CONTEXT (t), args, complain, in_decl);
- if (dependent_scope_p (context))
+ if ((complain & tf_dguide) && dependent_scope_p (context))
{
/* When rewriting a constructor into a deduction guide, a
non-dependent name can become dependent, so memtmpl<args>
@@ -21715,6 +21715,21 @@ instantiate_alias_template (tree tmpl, tree args, tsubst_flags_t complain)
if (tmpl == error_mark_node || args == error_mark_node)
return error_mark_node;
+ /* See maybe_dependent_member_ref. */
+ if (complain & tf_dguide)
+ {
+ tree ctx = tsubst_aggr_type (DECL_CONTEXT (tmpl), args, complain,
+ tmpl, true);
+ if (dependent_scope_p (ctx))
+ {
+ tree name = DECL_NAME (tmpl);
+ tree fullname = build_nt (TEMPLATE_ID_EXPR, name,
+ INNERMOST_TEMPLATE_ARGS (args));
+ tree tname = build_typename_type (ctx, name, fullname, typename_type);
+ return TYPE_NAME (tname);
+ }
+ }
+
args =
coerce_innermost_template_parms (DECL_TEMPLATE_PARMS (tmpl),
args, tmpl, complain,
@@ -29279,6 +29294,8 @@ build_deduction_guide (tree type, tree ctor, tree outer_args, tsubst_flags_t com
++processing_template_decl;
bool ok = true;
+ complain |= tf_dguide;
+
fn_tmpl
= (TREE_CODE (ctor) == TEMPLATE_DECL ? ctor
: DECL_TI_TEMPLATE (ctor));
diff --git a/gcc/testsuite/g++.dg/cpp2a/class-deduction-alias12.C b/gcc/testsuite/g++.dg/cpp2a/class-deduction-alias12.C
new file mode 100644
index 0000000..725e758
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/class-deduction-alias12.C
@@ -0,0 +1,23 @@
+// PR c++/104470
+// { dg-do compile { target c++20 } }
+
+template<typename _Types>
+class variant
+{
+ template<typename _Tp>
+ static constexpr int __accepted_index = 0;
+ template<int _Np>
+ using __to_type = int;
+ template<typename _Tp>
+ using __accepted_type = __to_type<__accepted_index<_Tp>>;
+ template<typename _Tp, typename _Tj = __accepted_type<_Tp>>
+ variant(_Tp __t) { }
+};
+template <typename T>
+struct Foo
+{
+ T value;
+};
+template <typename T>
+using V = variant<Foo<T>>;
+V e = Foo{1}; // { dg-error "" }
diff --git a/gcc/testsuite/g++.dg/cpp2a/explicit11.C b/gcc/testsuite/g++.dg/cpp2a/explicit11.C
index 2df42cd..b6adfd0 100644
--- a/gcc/testsuite/g++.dg/cpp2a/explicit11.C
+++ b/gcc/testsuite/g++.dg/cpp2a/explicit11.C
@@ -26,4 +26,4 @@ struct B {
template<typename U> B(U, TA<U>);
};
-B b{(int *)0, (char *)0};
+B b{(int *)0, (char *)0}; // { dg-error "deduction|no match" }