Message ID | 20240807150900.1390001-1-ppalka@redhat.com |
---|---|
State | New |
Headers | show |
Series | c++: erroneous partial spec vs primary tmpl [PR116064] | expand |
On 8/7/24 11:09 AM, Patrick Palka wrote: > Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look > OK for trunk? OK. > -- >8 -- > > When a partial specialization is deemed erroneous at parse time, we > currently flag the primary template as erroneous instead. Later > at instantiation time we check if the primary template is erroneous > rather than the selected partial specialization, so at least we're > consistent. > > But it's better not to conflate a partial specialization with the > primary template since they're instantiated independenty. This avoids > rejecting the instantiation of A<int> in the below testcase. > > PR c++/116064 > > gcc/cp/ChangeLog: > > * error.cc (get_current_template): If the current scope is > a partial specialization, return it instead of the primary > template. > * pt.cc (instantiate_class_template): Pass the partial > specialization if any to maybe_diagnose_erroneous_template > instead of the primary template. > > gcc/testsuite/ChangeLog: > > * g++.dg/template/permissive-error2.C: New test. > --- > gcc/cp/error.cc | 6 +++++- > gcc/cp/pt.cc | 2 +- > gcc/testsuite/g++.dg/template/permissive-error2.C | 15 +++++++++++++++ > 3 files changed, 21 insertions(+), 2 deletions(-) > create mode 100644 gcc/testsuite/g++.dg/template/permissive-error2.C > > diff --git a/gcc/cp/error.cc b/gcc/cp/error.cc > index 6c22ff55b46..879e5a115cf 100644 > --- a/gcc/cp/error.cc > +++ b/gcc/cp/error.cc > @@ -173,7 +173,11 @@ get_current_template () > { > if (scope_chain && in_template_context && !current_instantiation ()) > if (tree ti = get_template_info (current_scope ())) > - return TI_TEMPLATE (ti); > + { > + if (PRIMARY_TEMPLATE_P (TI_TEMPLATE (ti)) && TI_PARTIAL_INFO (ti)) > + ti = TI_PARTIAL_INFO (ti); > + return TI_TEMPLATE (ti); > + } > > return NULL_TREE; > } > diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc > index 542962b6387..3e55d5c0fea 100644 > --- a/gcc/cp/pt.cc > +++ b/gcc/cp/pt.cc > @@ -12381,7 +12381,7 @@ instantiate_class_template (tree type) > if (! push_tinst_level (type)) > return type; > > - maybe_diagnose_erroneous_template (templ); > + maybe_diagnose_erroneous_template (t ? TI_TEMPLATE (t) : templ); > > int saved_unevaluated_operand = cp_unevaluated_operand; > int saved_inhibit_evaluation_warnings = c_inhibit_evaluation_warnings; > diff --git a/gcc/testsuite/g++.dg/template/permissive-error2.C b/gcc/testsuite/g++.dg/template/permissive-error2.C > new file mode 100644 > index 00000000000..692e7c7ac82 > --- /dev/null > +++ b/gcc/testsuite/g++.dg/template/permissive-error2.C > @@ -0,0 +1,15 @@ > +// PR c++/116064 > +// { dg-additional-options -fpermissive } > +// Verify we correctly mark a partial specialization as erroneous > +// instead its primary template. > + > +template<class T> > +struct A { }; > + > +template<class T> > +struct A<T*> { // { dg-error "instantiating erroneous template" } > + void f(typename A::type); // { dg-warning "does not name a type" } > +}; > + > +A<int> a; // { dg-bogus "" } > +A<int*> b; // { dg-message "required from here" }
diff --git a/gcc/cp/error.cc b/gcc/cp/error.cc index 6c22ff55b46..879e5a115cf 100644 --- a/gcc/cp/error.cc +++ b/gcc/cp/error.cc @@ -173,7 +173,11 @@ get_current_template () { if (scope_chain && in_template_context && !current_instantiation ()) if (tree ti = get_template_info (current_scope ())) - return TI_TEMPLATE (ti); + { + if (PRIMARY_TEMPLATE_P (TI_TEMPLATE (ti)) && TI_PARTIAL_INFO (ti)) + ti = TI_PARTIAL_INFO (ti); + return TI_TEMPLATE (ti); + } return NULL_TREE; } diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index 542962b6387..3e55d5c0fea 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -12381,7 +12381,7 @@ instantiate_class_template (tree type) if (! push_tinst_level (type)) return type; - maybe_diagnose_erroneous_template (templ); + maybe_diagnose_erroneous_template (t ? TI_TEMPLATE (t) : templ); int saved_unevaluated_operand = cp_unevaluated_operand; int saved_inhibit_evaluation_warnings = c_inhibit_evaluation_warnings; diff --git a/gcc/testsuite/g++.dg/template/permissive-error2.C b/gcc/testsuite/g++.dg/template/permissive-error2.C new file mode 100644 index 00000000000..692e7c7ac82 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/permissive-error2.C @@ -0,0 +1,15 @@ +// PR c++/116064 +// { dg-additional-options -fpermissive } +// Verify we correctly mark a partial specialization as erroneous +// instead its primary template. + +template<class T> +struct A { }; + +template<class T> +struct A<T*> { // { dg-error "instantiating erroneous template" } + void f(typename A::type); // { dg-warning "does not name a type" } +}; + +A<int> a; // { dg-bogus "" } +A<int*> b; // { dg-message "required from here" }