On Mon, Jan 13, 2025 at 11:25:25AM -0500, Patrick Palka wrote: > Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look > OK for trunk?
Looks okay to me. > -- >8 -- > > PR c++/116417 > > gcc/cp/ChangeLog: > > * cp-tree.h (finish_pseudo_destructor_expr): Add complain > parameter. > * parser.cc (cp_parser_postfix_dot_deref_expression): Pass > complain=tf_warning_or_error to finish_pseudo_destructor_expr. > * pt.cc (tsubst_expr): Pass complain to > finish_pseudo_destructor_expr. > * semantics.cc (finish_pseudo_destructor_expr): Check complain > before issuing a diagnostic. > > gcc/testsuite/ChangeLog: > > * g++.dg/template/pseudodtor7.C: New test. > --- > gcc/cp/cp-tree.h | 2 +- > gcc/cp/parser.cc | 3 ++- > gcc/cp/pt.cc | 4 ++-- > gcc/cp/semantics.cc | 15 +++++++++------ > gcc/testsuite/g++.dg/template/pseudodtor7.C | 15 +++++++++++++++ > 5 files changed, 29 insertions(+), 10 deletions(-) > create mode 100644 gcc/testsuite/g++.dg/template/pseudodtor7.C > > diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h > index aed58523b16..1b42e8ba7d8 100644 > --- a/gcc/cp/cp-tree.h > +++ b/gcc/cp/cp-tree.h > @@ -7966,7 +7966,7 @@ extern tree lookup_and_finish_template_variable (tree, > tree, tsubst_flags_t = tf > extern tree finish_template_variable (tree, tsubst_flags_t = > tf_warning_or_error); > extern cp_expr finish_increment_expr (cp_expr, enum tree_code); > extern tree finish_this_expr (void); > -extern tree finish_pseudo_destructor_expr (tree, tree, tree, > location_t); > +extern tree finish_pseudo_destructor_expr (tree, tree, tree, > location_t, tsubst_flags_t); > extern cp_expr finish_unary_op_expr (location_t, enum tree_code, > cp_expr, > tsubst_flags_t); > /* Whether this call to finish_compound_literal represents a C++11 functional > diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc > index f548dc31c2b..7f4340537c9 100644 > --- a/gcc/cp/parser.cc > +++ b/gcc/cp/parser.cc > @@ -8847,7 +8847,8 @@ cp_parser_postfix_dot_deref_expression (cp_parser > *parser, > pseudo_destructor_p = true; > postfix_expression > = finish_pseudo_destructor_expr (postfix_expression, > - s, type, location); > + s, type, location, > + tf_warning_or_error); > } > } > > diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc > index a141de56446..537e4c4a494 100644 > --- a/gcc/cp/pt.cc > +++ b/gcc/cp/pt.cc > @@ -21537,7 +21537,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t > complain, tree in_decl) > tree op1 = RECUR (TREE_OPERAND (t, 1)); > tree op2 = tsubst (TREE_OPERAND (t, 2), args, complain, in_decl); > RETURN (finish_pseudo_destructor_expr (op0, op1, op2, > - input_location)); > + input_location, complain)); > } > > case TREE_LIST: > @@ -21601,7 +21601,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t > complain, tree in_decl) > dtor = TREE_OPERAND (dtor, 0); > if (TYPE_P (dtor)) > RETURN (finish_pseudo_destructor_expr > - (object, s, dtor, input_location)); > + (object, s, dtor, input_location, complain)); > } > } > } > diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc > index 15840e10620..76c79c6a8cc 100644 > --- a/gcc/cp/semantics.cc > +++ b/gcc/cp/semantics.cc > @@ -3527,7 +3527,7 @@ finish_this_expr (void) > > tree > finish_pseudo_destructor_expr (tree object, tree scope, tree destructor, > - location_t loc) > + location_t loc, tsubst_flags_t complain) > { > if (object == error_mark_node || destructor == error_mark_node) > return error_mark_node; > @@ -3538,16 +3538,18 @@ finish_pseudo_destructor_expr (tree object, tree > scope, tree destructor, > { > if (scope == error_mark_node) > { > - error_at (loc, "invalid qualifying scope in pseudo-destructor name"); > + if (complain & tf_error) > + error_at (loc, "invalid qualifying scope in pseudo-destructor > name"); > return error_mark_node; > } > if (is_auto (destructor)) > destructor = TREE_TYPE (object); > if (scope && TYPE_P (scope) && !check_dtor_name (scope, destructor)) > { > - error_at (loc, > - "qualified type %qT does not match destructor name ~%qT", > - scope, destructor); > + if (complain & tf_error) > + error_at (loc, > + "qualified type %qT does not match destructor name ~%qT", > + scope, destructor); > return error_mark_node; > } > > @@ -3568,7 +3570,8 @@ finish_pseudo_destructor_expr (tree object, tree scope, > tree destructor, > if (!same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (object), > destructor)) > { > - error_at (loc, "%qE is not of type %qT", object, destructor); > + if (complain & tf_error) > + error_at (loc, "%qE is not of type %qT", object, destructor); > return error_mark_node; > } > } > diff --git a/gcc/testsuite/g++.dg/template/pseudodtor7.C > b/gcc/testsuite/g++.dg/template/pseudodtor7.C > new file mode 100644 > index 00000000000..302b8c96625 > --- /dev/null > +++ b/gcc/testsuite/g++.dg/template/pseudodtor7.C > @@ -0,0 +1,15 @@ > +// PR c++/116417 > +// { dg-do compile { target c++11 } } > + > +template<class T> > +T&& declval(); > + > +template<class T, class = decltype(declval<T>().~T())> > +void f(int) = delete; > + > +template<class T> > +void f(...); > + > +int main() { > + f<int&>(0); > +} > -- > 2.48.0.rc1.35.g1b4e9a5f8b > Marek