Index: cp/cp-tree.h =================================================================== --- cp/cp-tree.h (revision 202503) +++ cp/cp-tree.h (working copy) @@ -5734,7 +5734,7 @@ extern tree finish_call_expr (tree, veclexer); + sloc = token->location; /* Some of the productions are determined by keywords. */ keyword = token->keyword; switch (keyword) @@ -6019,7 +6021,7 @@ cp_parser_postfix_expression (cp_parser *parser, b = cp_parser_postfix_dot_deref_expression (parser, token->type, postfix_expression, false, &idk, - token->location); + sloc); is_member_access = true; break; @@ -6338,7 +6340,7 @@ cp_parser_postfix_dot_deref_expression (cp_parser pseudo_destructor_p = true; postfix_expression = finish_pseudo_destructor_expr (postfix_expression, - s, type); + s, type, location); } } Index: cp/pt.c =================================================================== --- cp/pt.c (revision 202503) +++ cp/pt.c (working copy) @@ -5398,7 +5398,8 @@ unify_arg_conversion (bool explain_p, tree to_type tree from_type, tree arg) { if (explain_p) - inform (input_location, " cannot convert %qE (type %qT) to type %qT", + inform (EXPR_LOC_OR_HERE (arg), + " cannot convert %qE (type %qT) to type %qT", arg, from_type, to_type); return 1; } @@ -14292,9 +14293,10 @@ tsubst_copy_and_build (tree t, case PSEUDO_DTOR_EXPR: RETURN (finish_pseudo_destructor_expr - (RECUR (TREE_OPERAND (t, 0)), - RECUR (TREE_OPERAND (t, 1)), - tsubst (TREE_OPERAND (t, 2), args, complain, in_decl))); + (RECUR (TREE_OPERAND (t, 0)), + RECUR (TREE_OPERAND (t, 1)), + tsubst (TREE_OPERAND (t, 2), args, complain, in_decl), + input_location)); case TREE_LIST: { @@ -14423,7 +14425,8 @@ tsubst_copy_and_build (tree t, { dtor = TREE_OPERAND (dtor, 0); if (TYPE_P (dtor)) - RETURN (finish_pseudo_destructor_expr (object, s, dtor)); + RETURN (finish_pseudo_destructor_expr + (object, s, dtor, input_location)); } } } Index: cp/semantics.c =================================================================== --- cp/semantics.c (revision 202503) +++ cp/semantics.c (working copy) @@ -2361,7 +2361,8 @@ finish_this_expr (void) was of the form `OBJECT.SCOPE::~DESTRUCTOR'. */ tree -finish_pseudo_destructor_expr (tree object, tree scope, tree destructor) +finish_pseudo_destructor_expr (tree object, tree scope, tree destructor, + location_t loc) { if (object == error_mark_node || destructor == error_mark_node) return error_mark_node; @@ -2372,15 +2373,16 @@ tree { if (scope == error_mark_node) { - error ("invalid qualifying scope in pseudo-destructor name"); + 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 ("qualified type %qT does not match destructor name ~%qT", - scope, destructor); + error_at (loc, + "qualified type %qT does not match destructor name ~%qT", + scope, destructor); return error_mark_node; } @@ -2401,12 +2403,13 @@ tree if (!same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (object), destructor)) { - error ("%qE is not of type %qT", object, destructor); + error_at (loc, "%qE is not of type %qT", object, destructor); return error_mark_node; } } - return build3 (PSEUDO_DTOR_EXPR, void_type_node, object, scope, destructor); + return build3_loc (loc, PSEUDO_DTOR_EXPR, void_type_node, object, + scope, destructor); } /* Finish an expression of the form CODE EXPR. */ Index: testsuite/g++.dg/template/pseudodtor2.C =================================================================== --- testsuite/g++.dg/template/pseudodtor2.C (revision 202503) +++ testsuite/g++.dg/template/pseudodtor2.C (working copy) @@ -6,7 +6,7 @@ template struct D typedef int T; S foo (); - D () { foo ().~T(); } // { dg-error "is not of type" } + D () { foo ().~T(); } // { dg-error "10:is not of type" } }; struct Z Index: testsuite/g++.dg/template/pseudodtor3.C =================================================================== --- testsuite/g++.dg/template/pseudodtor3.C (revision 202503) +++ testsuite/g++.dg/template/pseudodtor3.C (working copy) @@ -5,13 +5,13 @@ struct A { typedef int T; T &foo (); - A () { foo.~T (); } // { dg-error "does not have class type|expected" } + A () { foo.~T (); } // { dg-error "10:does not have class type|expected" } }; template struct B { T &foo (); - B () { foo.~T (); } // { dg-error "invalid use of member" } + B () { foo.~T (); } // { dg-error "10:invalid use of member" } }; B b; @@ -19,7 +19,7 @@ B b; template struct C { T t; - C () { t.~S (); } // { dg-error "is not of type" } + C () { t.~S (); } // { dg-error "10:is not of type" } }; C c; @@ -28,7 +28,7 @@ template struct D { T t; typedef long int U; - D () { t.~U (); } // { dg-error "is not of type" } + D () { t.~U (); } // { dg-error "10:is not of type" } }; D d; @@ -37,7 +37,7 @@ template struct E { T &foo (); typedef long int U; - E () { foo.~U (); } // { dg-error "is not of type" } + E () { foo.~U (); } // { dg-error "10:is not of type" } }; E e;