Hi! This PR is complaining about range covering the first token from an id-expression: pr87386.C:4:15: error: static assertion failed: foo 4 | static_assert(foo::test<int>::value, "foo"); | ^~~ The following patch adjust that to: pr87386.C:4:31: error: static assertion failed: foo 4 | static_assert(foo::test<int>::value, "foo"); | ~~~~~~~~~~~~~~~~^~~~~ instead, though as the changes to the testsuite show, not really sure if it is a good idea in all cases, because then we sometimes print: ... bar is not in foo namespace, did you mean 'baz' foo::bar ~~~~~^~~ baz where the baz is misaligned. Would it be better to just print pr87386.C:4:31: error: static assertion failed: foo 4 | static_assert(foo::test<int>::value, "foo"); | ^~~~~ instead? That would mean dropping the cp_parser_id_expression change and readjusting or dropping some testsuite changes.
2018-11-20 Jakub Jelinek <ja...@redhat.com> PR c++/87386 * parser.c (cp_parser_primary_expression): Use id_expression.get_location () instead of id_expr_token->location. (cp_parser_id_expression): For nested_name_specifier_p, make a range covering whole id-expression. (cp_parser_operator): For operator "" make a range from "" to the end of the suffix with caret at the start of the id. gcc/testsuite/ * g++.dg/spellcheck-pr79298.C: Adjust expected diagnostics. * g++.dg/lookup/suggestions2.C: Likewise. * g++.dg/spellcheck-single-vs-multiple.C: Likewise. * g++.dg/parse/error17.C: Likewise. * g++.dg/spellcheck-pr77829.C: Likewise. * g++.dg/spellcheck-pr78656.C: Likewise. * g++.dg/cpp0x/pr51420.C: Likewise. * g++.dg/cpp0x/udlit-declare-neg.C: Likewise. * g++.dg/cpp0x/udlit-member-neg.C: Likewise. libstdc++-v3/ * testsuite/20_util/scoped_allocator/69293_neg.cc: Adjust expected line. * testsuite/20_util/uses_allocator/cons_neg.cc: Likewise. * testsuite/experimental/propagate_const/requirements2.cc: Likewise. * testsuite/experimental/propagate_const/requirements3.cc: Likewise. * testsuite/experimental/propagate_const/requirements4.cc: Likewise. * testsuite/experimental/propagate_const/requirements5.cc: Likewise. --- gcc/cp/parser.c.jj 2018-11-20 08:41:28.686923718 +0100 +++ gcc/cp/parser.c 2018-11-20 19:05:22.848941522 +0100 @@ -5602,7 +5602,7 @@ cp_parser_primary_expression (cp_parser /*is_namespace=*/false, /*check_dependency=*/true, &ambiguous_decls, - id_expr_token->location); + id_expression.get_location ()); /* If the lookup was ambiguous, an error will already have been issued. */ if (ambiguous_decls) @@ -5673,7 +5673,7 @@ cp_parser_primary_expression (cp_parser if (parser->local_variables_forbidden_p && local_variable_p (decl)) { - error_at (id_expr_token->location, + error_at (id_expression.get_location (), "local variable %qD may not appear in this context", decl.get_value ()); return error_mark_node; @@ -5692,7 +5692,7 @@ cp_parser_primary_expression (cp_parser id_expression.get_location ())); if (error_msg) cp_parser_error (parser, error_msg); - decl.set_location (id_expr_token->location); + decl.set_location (id_expression.get_location ()); return decl; } @@ -5758,6 +5758,7 @@ cp_parser_id_expression (cp_parser *pars { bool global_scope_p; bool nested_name_specifier_p; + location_t start_loc = cp_lexer_peek_token (parser->lexer)->location; /* Assume the `template' keyword was not used. */ if (template_p) @@ -5809,6 +5810,7 @@ cp_parser_id_expression (cp_parser *pars parser->object_scope = saved_object_scope; parser->qualifying_scope = saved_qualifying_scope; + unqualified_id.set_range (start_loc, unqualified_id.get_finish ()); return unqualified_id; } /* Otherwise, if we are in global scope, then we are looking at one @@ -14931,7 +14933,7 @@ cp_literal_operator_id (const char* name static cp_expr cp_parser_operator (cp_parser* parser) { - tree id = NULL_TREE; + cp_expr id = NULL_TREE; cp_token *token; bool utf8 = false; @@ -15219,8 +15221,9 @@ cp_parser_operator (cp_parser* parser) if (id != error_mark_node) { const char *name = IDENTIFIER_POINTER (id); - id = cp_literal_operator_id (name); + *id = cp_literal_operator_id (name); } + id.set_range (start_loc, id.get_finish ()); return id; } @@ -15244,7 +15247,8 @@ cp_parser_operator (cp_parser* parser) id = error_mark_node; } - return cp_expr (id, start_loc); + id.set_location (start_loc); + return id; } /* Parse a template-declaration. --- gcc/testsuite/g++.dg/spellcheck-pr79298.C.jj 2018-10-31 10:31:13.281572644 +0100 +++ gcc/testsuite/g++.dg/spellcheck-pr79298.C 2018-11-20 19:14:19.208219955 +0100 @@ -11,7 +11,7 @@ int foo () return M::y; // { dg-error ".y. is not a member of .M." } /* { dg-begin-multiline-output "" } return M::y; - ^ + ~~~^ { dg-end-multiline-output "" } */ } @@ -20,7 +20,7 @@ int bar () return O::colour; // { dg-error ".colour. is not a member of .O.; did you mean 'color'\\?" } /* { dg-begin-multiline-output "" } return O::colour; - ^~~~~~ - color + ~~~^~~~~~ + color { dg-end-multiline-output "" } */ } --- gcc/testsuite/g++.dg/lookup/suggestions2.C.jj 2018-10-31 10:31:06.928677642 +0100 +++ gcc/testsuite/g++.dg/lookup/suggestions2.C 2018-11-20 19:12:05.281395810 +0100 @@ -33,8 +33,8 @@ int test_1_long (void) { return outer_ns::var_in_inner_ns_a; // { dg-error "did you mean 'var_in_outer_ns'" } /* { dg-begin-multiline-output "" } return outer_ns::var_in_inner_ns_a; - ^~~~~~~~~~~~~~~~~ - var_in_outer_ns + ~~~~~~~~~~^~~~~~~~~~~~~~~~~ + var_in_outer_ns { dg-end-multiline-output "" } */ } @@ -45,7 +45,7 @@ int test_1_short (void) { return outer_ns::a; // { dg-error "did you mean 'outer_ns::inner_ns_a::a'" } /* { dg-begin-multiline-output "" } return outer_ns::a; - ^ + ~~~~~~~~~~^ { dg-end-multiline-output "" } */ // { dg-message "declared here" "" { target *-*-*} decl_of_a } /* { dg-begin-multiline-output "" } @@ -61,8 +61,8 @@ int test_2_long (void) { return outer_ns::inner_ns_a::var_in_outer_ns; // { dg-error "did you mean 'var_in_inner_ns_a'" } /* { dg-begin-multiline-output "" } return outer_ns::inner_ns_a::var_in_outer_ns; - ^~~~~~~~~~~~~~~ - var_in_inner_ns_a + ~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~ + var_in_inner_ns_a { dg-end-multiline-output "" } */ } @@ -73,7 +73,7 @@ int test_2_short (void) { return outer_ns::inner_ns_a::o; // { dg-error "did you mean 'outer_ns::o'" } /* { dg-begin-multiline-output "" } return outer_ns::inner_ns_a::o; - ^ + ~~~~~~~~~~~~~~~~~~~~~~^ { dg-end-multiline-output "" } */ // { dg-message "declared here" "" { target *-*-*} decl_of_o } /* { dg-begin-multiline-output "" } @@ -89,8 +89,8 @@ int test_3_long (void) { return outer_ns::inner_ns_a::var_in_inner_ns_b; // { dg-error "did you mean 'var_in_inner_ns_a'" } /* { dg-begin-multiline-output "" } return outer_ns::inner_ns_a::var_in_inner_ns_b; - ^~~~~~~~~~~~~~~~~ - var_in_inner_ns_a + ~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~ + var_in_inner_ns_a { dg-end-multiline-output "" } */ } @@ -101,7 +101,7 @@ int test_3_short (void) { return outer_ns::inner_ns_a::b; // { dg-error "did you mean 'outer_ns::inner_ns_b::b'" } /* { dg-begin-multiline-output "" } return outer_ns::inner_ns_a::b; - ^ + ~~~~~~~~~~~~~~~~~~~~~~^ { dg-end-multiline-output "" } */ // { dg-message "declared here" "" { target *-*-*} decl_of_b } /* { dg-begin-multiline-output "" } --- gcc/testsuite/g++.dg/spellcheck-single-vs-multiple.C.jj 2018-10-31 10:31:07.765663807 +0100 +++ gcc/testsuite/g++.dg/spellcheck-single-vs-multiple.C 2018-11-20 19:14:35.698952024 +0100 @@ -73,7 +73,7 @@ void test_3 () ns3::goo_3 (); // { dg-error "'goo_3' is not a member of 'ns3'; did you mean 'foo_3'\\?" } /* { dg-begin-multiline-output "" } ns3::goo_3 (); - ^~~~~ - foo_3 + ~~~~~^~~~~ + foo_3 { dg-end-multiline-output "" } */ } --- gcc/testsuite/g++.dg/parse/error17.C.jj 2009-11-27 12:25:22.000000000 +0100 +++ gcc/testsuite/g++.dg/parse/error17.C 2018-11-20 19:12:35.212909527 +0100 @@ -6,4 +6,4 @@ template <typename T> struct B { }; struct D : B<int>, B<char> {}; -int i2 = D::Bar(2); // { dg-error "10:reference to 'Bar' is ambiguous" } +int i2 = D::Bar(2); // { dg-error "13:reference to 'Bar' is ambiguous" } --- gcc/testsuite/g++.dg/spellcheck-pr77829.C.jj 2018-10-31 10:31:10.213623350 +0100 +++ gcc/testsuite/g++.dg/spellcheck-pr77829.C 2018-11-20 19:13:30.700008045 +0100 @@ -21,8 +21,8 @@ void fn_1_explicit () detail::some_type i; // { dg-error ".some_type. is not a member of .detail.; did you mean 'some_typedef'\\?" } /* { dg-begin-multiline-output "" } detail::some_type i; - ^~~~~~~~~ - some_typedef + ~~~~~~~~^~~~~~~~~ + some_typedef { dg-end-multiline-output "" } */ } @@ -47,8 +47,8 @@ void fn_2_explicit (int i) { detail::foo(i); // { dg-error ".foo. is not a member of .detail.; did you mean '_foo'\\?" } /* { dg-begin-multiline-output "" } detail::foo(i); - ^~~ - _foo + ~~~~~~~~^~~ + _foo { dg-end-multiline-output "" } */ } @@ -72,8 +72,8 @@ void fn_3_explicit (int i) { detail::something_els(i); // { dg-error ".something_els. is not a member of .detail.; did you mean 'something_else'\\?" } /* { dg-begin-multiline-output "" } detail::something_els(i); - ^~~~~~~~~~~~~ - something_else + ~~~~~~~~^~~~~~~~~~~~~ + something_else { dg-end-multiline-output "" } */ } @@ -97,7 +97,7 @@ void fn_4_explicit (int i) { detail::not_recognized(i); // { dg-error ".not_recognized. is not a member of .detail." } /* { dg-begin-multiline-output "" } detail::not_recognized(i); - ^~~~~~~~~~~~~~ + ~~~~~~~~^~~~~~~~~~~~~~ { dg-end-multiline-output "" } */ } --- gcc/testsuite/g++.dg/spellcheck-pr78656.C.jj 2018-10-31 10:31:10.213623350 +0100 +++ gcc/testsuite/g++.dg/spellcheck-pr78656.C 2018-11-20 19:14:04.161464402 +0100 @@ -7,8 +7,8 @@ void* allocate(std::size_t n) return std::allocate<char>().allocate(n); // { dg-error ".allocate. is not a member of .std.; did you mean 'allocator'\\?" } /* { dg-begin-multiline-output "" } return std::allocate<char>().allocate(n); - ^~~~~~~~ - allocator + ~~~~~^~~~~~~~ + allocator { dg-end-multiline-output "" } */ // Various errors follow that we don't care about; suppress them: @@ -20,8 +20,8 @@ void* test_2(std::size_t n) return std::alocator<char>().allocate(n); // { dg-error ".alocator. is not a member of .std.; did you mean 'allocator'\\?" } /* { dg-begin-multiline-output "" } return std::alocator<char>().allocate(n); - ^~~~~~~~ - allocator + ~~~~~^~~~~~~~ + allocator { dg-end-multiline-output "" } */ // Various errors follow that we don't care about; suppress them: --- gcc/testsuite/g++.dg/cpp0x/pr51420.C.jj 2016-05-30 23:22:54.772099149 +0200 +++ gcc/testsuite/g++.dg/cpp0x/pr51420.C 2018-11-20 19:06:05.236252077 +0100 @@ -3,6 +3,6 @@ void foo() { - float x = operator"" _F(); // { dg-error "13:'operator\"\"_F' was not declared in this scope" } + float x = operator"" _F(); // { dg-error "24:'operator\"\"_F' was not declared in this scope" } float y = 0_F; // { dg-error "unable to find numeric literal operator" } } --- gcc/testsuite/g++.dg/cpp0x/udlit-declare-neg.C.jj 2016-05-30 23:22:54.772099149 +0200 +++ gcc/testsuite/g++.dg/cpp0x/udlit-declare-neg.C 2018-11-20 19:07:08.835217615 +0100 @@ -2,14 +2,14 @@ // Check that undeclared literal operator calls and literals give appropriate errors. -int i = operator"" _Bar('x'); // { dg-error "9:'operator\"\"_Bar' was not declared in this scope" } +int i = operator"" _Bar('x'); // { dg-error "20:'operator\"\"_Bar' was not declared in this scope" } int j = 'x'_Bar; // { dg-error "unable to find character literal operator|with|argument" } -int ii = operator"" _BarCharStr("Howdy, Pardner!"); // { dg-error "10:'operator\"\"_BarCharStr' was not declared in this scope" } +int ii = operator"" _BarCharStr("Howdy, Pardner!"); // { dg-error "21:'operator\"\"_BarCharStr' was not declared in this scope" } int jj = "Howdy, Pardner!"_BarCharStr; // { dg-error "unable to find string literal operator|Possible missing length argument" } -unsigned long long iULL = operator"" _BarULL(666ULL); // { dg-error "27:'operator\"\"_BarULL' was not declared in this scope" } +unsigned long long iULL = operator"" _BarULL(666ULL); // { dg-error "38:'operator\"\"_BarULL' was not declared in this scope" } unsigned long long jULL = 666_BarULL; // { dg-error "unable to find numeric literal operator" } -long double iLD = operator"" _BarLD(666.0L); // { dg-error "19:'operator\"\"_BarLD' was not declared in this scope" } +long double iLD = operator"" _BarLD(666.0L); // { dg-error "30:'operator\"\"_BarLD' was not declared in this scope" } long double jLD = 666.0_BarLD; // { dg-error "unable to find numeric literal operator" } --- gcc/testsuite/g++.dg/cpp0x/udlit-member-neg.C.jj 2018-06-14 21:01:40.000000000 +0200 +++ gcc/testsuite/g++.dg/cpp0x/udlit-member-neg.C 2018-11-20 19:22:56.470816139 +0100 @@ -7,7 +7,7 @@ public: int operator"" _Bar(char32_t); // { dg-error "7:.int Foo::operator\"\"_Bar\\(char32_t\\). must be a non-member function" } }; -int i = operator"" _Bar(U'x'); // { dg-error "9:'operator\"\"_Bar' was not declared in this scope" } +int i = operator"" _Bar(U'x'); // { dg-error "20:'operator\"\"_Bar' was not declared in this scope" } int j = U'x'_Bar; // { dg-error "unable to find character literal operator" } int --- libstdc++-v3/testsuite/20_util/scoped_allocator/69293_neg.cc.jj 2018-07-27 22:20:29.000000000 +0200 +++ libstdc++-v3/testsuite/20_util/scoped_allocator/69293_neg.cc 2018-11-20 21:20:25.123636254 +0100 @@ -46,5 +46,5 @@ test01() scoped_alloc sa; auto p = sa.allocate(1); sa.construct(p); // this is required to be ill-formed - // { dg-error "static assertion failed" "" { target *-*-* } 94 } + // { dg-error "static assertion failed" "" { target *-*-* } 96 } } --- libstdc++-v3/testsuite/20_util/uses_allocator/cons_neg.cc.jj 2018-07-27 22:20:29.000000000 +0200 +++ libstdc++-v3/testsuite/20_util/uses_allocator/cons_neg.cc 2018-11-20 21:21:12.868864599 +0100 @@ -43,4 +43,4 @@ void test01() tuple<Type> t(allocator_arg, a, 1); } -// { dg-error "static assertion failed" "" { target *-*-* } 94 } +// { dg-error "static assertion failed" "" { target *-*-* } 96 } --- libstdc++-v3/testsuite/experimental/propagate_const/requirements3.cc.jj 2018-01-03 18:53:16.000000000 +0100 +++ libstdc++-v3/testsuite/experimental/propagate_const/requirements3.cc 2018-11-20 21:22:06.049005105 +0100 @@ -21,6 +21,6 @@ using std::experimental::propagate_const; -// { dg-error "requires a class or a pointer to an object type" "" { target *-*-* } 105 } +// { dg-error "requires a class or a pointer to an object type" "" { target *-*-* } 107 } propagate_const<void (*)()> test1; --- libstdc++-v3/testsuite/experimental/propagate_const/requirements4.cc.jj 2018-01-03 18:53:16.000000000 +0100 +++ libstdc++-v3/testsuite/experimental/propagate_const/requirements4.cc 2018-11-20 21:22:29.698622883 +0100 @@ -21,7 +21,7 @@ using std::experimental::propagate_const; -// { dg-error "requires a class or a pointer to an object type" "" { target *-*-* } 105 } +// { dg-error "requires a class or a pointer to an object type" "" { target *-*-* } 107 } // { dg-error "invalid type" "" { target *-*-* } 66 } // { dg-error "uninitialized reference member" "" { target *-*-* } 112 } --- libstdc++-v3/testsuite/experimental/propagate_const/requirements5.cc.jj 2018-01-03 18:53:16.000000000 +0100 +++ libstdc++-v3/testsuite/experimental/propagate_const/requirements5.cc 2018-11-20 21:22:45.311370550 +0100 @@ -21,6 +21,6 @@ using std::experimental::propagate_const; -// { dg-error "requires a class or a pointer to an object type" "" { target *-*-* } 105 } +// { dg-error "requires a class or a pointer to an object type" "" { target *-*-* } 107 } propagate_const<int[1]> test1; --- libstdc++-v3/testsuite/experimental/propagate_const/requirements2.cc.jj 2018-01-03 18:53:16.000000000 +0100 +++ libstdc++-v3/testsuite/experimental/propagate_const/requirements2.cc 2018-11-20 21:21:43.959362116 +0100 @@ -21,7 +21,7 @@ using std::experimental::propagate_const; -// { dg-error "requires a class or a pointer to an object type" "" { target *-*-* } 105 } +// { dg-error "requires a class or a pointer to an object type" "" { target *-*-* } 107 } // { dg-error "not a pointer-to-object type" "" { target *-*-* } 66 } // { dg-error "forming pointer to reference type" "" { target *-*-* } 187 } // { dg-error "forming pointer to reference type" "" { target *-*-* } 213 } Jakub