diff options
author | Jason Merrill <jason@redhat.com> | 2020-08-14 18:01:27 -0400 |
---|---|---|
committer | Jason Merrill <jason@redhat.com> | 2020-08-18 16:20:09 -0400 |
commit | b871301f09be7061904dc87880919d30e6afef8f (patch) | |
tree | a4cad1e376c3f4c63ca7df8e5bc765687314aa72 /gcc | |
parent | 9125cf8c33b710c378bfb3c7e67ec2f9f1c523c9 (diff) | |
download | gcc-b871301f09be7061904dc87880919d30e6afef8f.zip gcc-b871301f09be7061904dc87880919d30e6afef8f.tar.gz gcc-b871301f09be7061904dc87880919d30e6afef8f.tar.bz2 |
c++: Rewrite members for all deduction guides. [PR96199]
After the last patch, it occurred to me that we could run into the
specialization issue with non-alias deduction guides as well, so this patch
extends the rewriting to C++17 mode.
Doing this revealed that we weren't properly pushing into class scope for
normalization.
gcc/cp/ChangeLog:
PR c++/96199
* pt.c (tsubst_aggr_type): Rewrite in C++17, too.
(maybe_dependent_member_ref): Likewise.
(build_deduction_guide): Re-substitute template parms.
* cp-tree.h (struct push_nested_class_guard): New.
* constraint.cc (get_normalized_constraints_from_decl): Use it.
gcc/testsuite/ChangeLog:
PR c++/96199
* g++.dg/cpp1z/class-deduction-spec1.C: New test.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/constraint.cc | 2 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 18 | ||||
-rw-r--r-- | gcc/cp/pt.c | 17 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp1z/class-deduction-spec1.C | 38 |
4 files changed, 71 insertions, 4 deletions
diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc index e4aace5..48d52ec 100644 --- a/gcc/cp/constraint.cc +++ b/gcc/cp/constraint.cc @@ -840,6 +840,8 @@ get_normalized_constraints_from_decl (tree d, bool diag = false) if (tree *p = hash_map_safe_get (normalized_map, tmpl)) return *p; + push_nested_class_guard pncs (DECL_CONTEXT (d)); + tree args = generic_targs_for (tmpl); tree ci = get_constraints (decl); tree norm = get_normalized_constraints_from_info (ci, args, tmpl, diag); diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 0475857..5ba82ee6 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -8137,6 +8137,24 @@ is_constrained_auto (const_tree t) return is_auto (t) && PLACEHOLDER_TYPE_CONSTRAINTS (t); } +/* RAII class to push/pop class scope T; if T is not a class, do nothing. */ + +struct push_nested_class_guard +{ + bool push; + push_nested_class_guard (tree t) + : push (t && CLASS_TYPE_P (t)) + { + if (push) + push_nested_class (t); + } + ~push_nested_class_guard () + { + if (push) + pop_nested_class (); + } +}; + #if CHECKING_P namespace selftest { extern void run_cp_tests (void); diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 585d944..8ad91b3 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -13391,7 +13391,7 @@ tsubst_aggr_type (tree t, complain, in_decl); if (argvec == error_mark_node) r = error_mark_node; - else if (cxx_dialect >= cxx20 && dependent_scope_p (context)) + else if (cxx_dialect >= cxx17 && dependent_scope_p (context)) { /* See maybe_dependent_member_ref. */ tree name = TYPE_IDENTIFIER (t); @@ -16328,14 +16328,13 @@ tsubst_init (tree init, tree decl, tree args, we are trying to refer to that member in a partial instantiation of C, return a SCOPE_REF; otherwise, return NULL_TREE. - This can happen when forming a C++20 alias template deduction guide, as in - PR96199. */ + This can happen when forming a C++17 deduction guide, as in PR96199. */ static tree maybe_dependent_member_ref (tree t, tree args, tsubst_flags_t complain, tree in_decl) { - if (cxx_dialect < cxx20) + if (cxx_dialect < cxx17) return NULL_TREE; tree ctx = context_for_name_lookup (t); @@ -28370,6 +28369,16 @@ build_deduction_guide (tree type, tree ctor, tree outer_args, tsubst_flags_t com fargs = tsubst (fargs, tsubst_args, complain, ctor); current_template_parms = save_parms; } + else + { + /* Substitute in the same arguments to rewrite class members into + references to members of an unknown specialization. */ + cp_evaluated ev; + fparms = tsubst_arg_types (fparms, targs, NULL_TREE, complain, ctor); + fargs = tsubst (fargs, targs, complain, ctor); + if (ci) + ci = tsubst_constraint_info (ci, targs, complain, ctor); + } --processing_template_decl; if (!ok) diff --git a/gcc/testsuite/g++.dg/cpp1z/class-deduction-spec1.C b/gcc/testsuite/g++.dg/cpp1z/class-deduction-spec1.C new file mode 100644 index 0000000..fcdf746 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1z/class-deduction-spec1.C @@ -0,0 +1,38 @@ +// PR c++/96199 +// { dg-do compile { target c++17 } } + +template<int> struct A1 { }; +template<int&> struct A2 { }; +template<class> struct A3 { }; + +int i; +template<typename V> struct B { + enum E { X }; + B(A1<X>, V) { } + + constexpr static V& ir = i; + B(A2<ir>, V) { } + + B(A3<E>, V) { } +}; + +// template<class T> B(A1<B<T>::X>,T) -> B<T>; +// template<class T> B(A2<B<T>::ir>,T) -> B<T>; +// template<class T> B(A3<typename B<T>::E>,T) -> B<T>; + +int j; +template <> struct B<int> { + using V = int; + + enum E { X = 1 }; + B(A1<X>, V) { } + + constexpr static V& ir = j; + B(A2<ir>, V) { } + + B(A3<E>, V) { } +}; + +B u1 { A1<1>(), 42 }; +B u2 { A2<j>(), 42 }; +B u3 { A3<B<int>::E>(), 42 }; |