Message ID | 20210323093417.GG231854@tucnak |
---|---|
State | New |
Headers | show |
Series | c++: Fix source_location inconsistency between calls from templates and non-templates [PR99672] | expand |
On 3/23/21 5:34 AM, Jakub Jelinek wrote: > Hi! > > The srcloc19.C testcase shows inconsistency in > std::source_location::current() locations between calls from > templates and non-templates. The location used by __builtin_source_location > comes in both cases from input_location which is set on it by bot_manip > when handling the default argument, called during finish_call_expr. > The problem is that in templates that input_location comes from the > CALL_EXPR we built earlier and that has the combined locus with > range between first character of the function name and closing paren > with caret on the opening paren, so something printed as caret as: > foobar (); > ~~~~~~~^~ > But outside of templates, finish_call_expr is called when input_location > is just the closing paren token, i.e. > foobar (); > ^ > and only after that returns we create the combined location and set > the CALL_EXPR location to that. So, it means std::source_location::current() > reports in templates the column of opening (, while outside of templates > closing ). > > The following patch makes it consistent by creating the combined location > already before calling finish_call_expr and temporarily overriding > input_location to that. > > Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? > > 2021-03-23 Jakub Jelinek <jakub@redhat.com> > > PR c++/99672 > * parser.c (cp_parser_postfix_expression): For calls, create > combined_loc and temporarily set input_location to it before > calling finish_call_expr. > > * g++.dg/concepts/diagnostic2.C: Adjust expected caret line. > * g++.dg/cpp1y/builtin_location.C (f4, n6): Move #line directives > to match locus changes. > * g++.dg/cpp2a/srcloc1.C: Adjust expected column numbers. > * g++.dg/cpp2a/srcloc2.C: Likewise. > * g++.dg/cpp2a/srcloc15.C: Likewise. > * g++.dg/cpp2a/srcloc16.C: Likewise. > * g++.dg/cpp2a/srcloc19.C: New test. > * g++.dg/modules/adhoc-1_b.C: Adjust expected column numbers > and caret line. > * g++.dg/modules/macloc-1_c.C: Adjust expected column numbers. > * g++.dg/modules/macloc-1_d.C: Likewise. > * g++.dg/plugin/diagnostic-test-expressions-1.C: Adjust expected > caret line. > > * testsuite/18_support/source_location/consteval.cc (main): Adjust > expected column numbers. > * testsuite/18_support/source_location/1.cc (main): Likewise. > > --- gcc/cp/parser.c.jj 2021-03-19 10:14:37.449724617 +0100 > +++ gcc/cp/parser.c 2021-03-19 17:35:11.216322995 +0100 > @@ -7564,6 +7564,7 @@ cp_parser_postfix_expression (cp_parser > tsubst_flags_t complain = complain_flags (decltype_p); > vec<tree, va_gc> *args; > location_t close_paren_loc = UNKNOWN_LOCATION; > + location_t combined_loc = UNKNOWN_LOCATION; > > is_member_access = false; > > @@ -7669,6 +7670,20 @@ cp_parser_postfix_expression (cp_parser > } > } > > + /* Temporarily set input_location to the combined location > + with call expression range, as e.g. build_out_target_exprs > + called from convert_default_arg relies on input_location, > + so updating it only when the call is fully built results > + in inconsistencies between location handling in templates > + and outside of templates. */ > + if (close_paren_loc != UNKNOWN_LOCATION) > + combined_loc = make_location (token->location, start_loc, > + close_paren_loc); > + auto cleanup > + = make_temp_override (input_location, > + combined_loc != UNKNOWN_LOCATION > + ? combined_loc : input_location); It's simpler to use iloc_sentinel for this. > + > if (TREE_CODE (postfix_expression) == COMPONENT_REF) > { > tree instance = TREE_OPERAND (postfix_expression, 0); > @@ -7726,12 +7741,7 @@ cp_parser_postfix_expression (cp_parser > complain); > > if (close_paren_loc != UNKNOWN_LOCATION) > - { > - location_t combined_loc = make_location (token->location, > - start_loc, > - close_paren_loc); > - postfix_expression.set_location (combined_loc); > - } > + postfix_expression.set_location (combined_loc); > > /* The POSTFIX_EXPRESSION is certainly no longer an id. */ > idk = CP_ID_KIND_NONE; > --- gcc/testsuite/g++.dg/concepts/diagnostic2.C.jj 2020-08-24 21:41:17.644520408 +0200 > +++ gcc/testsuite/g++.dg/concepts/diagnostic2.C 2021-03-22 19:04:59.947515357 +0100 > @@ -25,6 +25,6 @@ baz() > bar<int>(); // { dg-error "no match" } > /* { dg-begin-multiline-output "" } > bar<int>(); > - ^ > + ~~~~~~~~^~ > { dg-end-multiline-output "" } */ > } > --- gcc/testsuite/g++.dg/cpp1y/builtin_location.C.jj 2020-01-14 20:02:46.771610014 +0100 > +++ gcc/testsuite/g++.dg/cpp1y/builtin_location.C 2021-03-22 17:27:59.121756869 +0100 > @@ -103,10 +103,10 @@ A (0 == __builtin_strcmp (f3, FILE_3)); > #define FILE_4 "next_file_name.another_suffix" > #line 1 "foobar" > constexpr const char* f4 = this_file > - ( > #line 1 FILE_4 > - ) > + ( > #line 1 "foobar" > + ) > ; > A (0 == __builtin_strcmp (f4, FILE_4)); > > @@ -167,9 +167,9 @@ A (n5 == 9); > // of the function call. > #line 1 > constexpr int n6 = this_line > - ( > #line 99 > - ) > + ( > #line 1 > + ) > ; > A (n6 == 99); > --- gcc/testsuite/g++.dg/cpp2a/srcloc1.C.jj 2020-12-04 16:02:57.300153753 +0100 > +++ gcc/testsuite/g++.dg/cpp2a/srcloc1.C 2021-03-20 00:30:14.245469602 +0100 > @@ -80,7 +80,7 @@ constexpr source_location s2 = baz <1> ( > const source_location *p1 = &s1; > const source_location *p2 = &s2; > static_assert (source_location::current ().line () == __LINE__); > -static_assert (source_location::current ().column () == 42); > +static_assert (source_location::current ().column () == 41); > > constexpr bool > quux () > @@ -106,7 +106,7 @@ quux () > return false; > if (line1 != line2) > return false; > - if (column != 33) > + if (column != 32) > return false; > return true; > } > --- gcc/testsuite/g++.dg/cpp2a/srcloc2.C.jj 2020-12-04 16:02:57.300153753 +0100 > +++ gcc/testsuite/g++.dg/cpp2a/srcloc2.C 2021-03-20 00:30:14.245469602 +0100 > @@ -84,7 +84,7 @@ const source_location *p1 = &s1; > const source_location *p2 = &s2; > > static_assert (source_location::current ().line () == __LINE__); > -static_assert (source_location::current ().column () == 42); > +static_assert (source_location::current ().column () == 41); > > constexpr bool > quux () > @@ -110,7 +110,7 @@ quux () > return false; > if (line1 != line2) > return false; > - if (column != 33) > + if (column != 32) > return false; > return true; > } > --- gcc/testsuite/g++.dg/cpp2a/srcloc15.C.jj 2020-12-04 16:02:57.300153753 +0100 > +++ gcc/testsuite/g++.dg/cpp2a/srcloc15.C 2021-03-20 00:30:14.246469591 +0100 > @@ -69,8 +69,8 @@ bar () > source_location a = foo (); > source_location b = source_location::current (); > source_location c = foo (); > - // ^ column 28 > - // ^ column 49 > + // ^ column 27 > + // ^ column 48 > const source_location *d[3] = { &a, &b, &c }; > const char *file1 = __FILE__; > const char *function1 = __PRETTY_FUNCTION__; > @@ -83,7 +83,7 @@ bar () > return false; > if (d[j]->line () != line + j + 1) > return false; > - if (d[j]->column () != (j == 1 ? 49 : 28)) > + if (d[j]->column () != (j == 1 ? 48 : 27)) > return false; > } > > --- gcc/testsuite/g++.dg/cpp2a/srcloc16.C.jj 2020-12-03 23:21:57.709534533 +0100 > +++ gcc/testsuite/g++.dg/cpp2a/srcloc16.C 2021-03-20 00:30:14.246469591 +0100 > @@ -79,10 +79,10 @@ foo () > || u.u.line () + 1 != v.line () > || s.a.column () != 18 > || s.b.column () != 18 > - || s.c.column () != 50 > + || s.c.column () != 49 > || t.u.column () != 21 > || u.u.column () != 13 > - || v.column () != 49) > + || v.column () != 48) > return false; > return true; > } > --- gcc/testsuite/g++.dg/cpp2a/srcloc19.C.jj 2021-03-20 00:30:14.246469591 +0100 > +++ gcc/testsuite/g++.dg/cpp2a/srcloc19.C 2021-03-20 00:30:14.246469591 +0100 > @@ -0,0 +1,44 @@ > +// PR c++/99672 > +// { dg-do compile { target c++20 } } > + > +namespace std { > + struct source_location { > + struct __impl { > + const char *_M_file_name; > + const char *_M_function_name; > + unsigned int _M_line, _M_column; > + }; > + const __impl *__ptr; > + constexpr source_location () : __ptr (nullptr) {} > + static consteval source_location > + current (const void *__p = __builtin_source_location ()) { > + source_location __ret; > + __ret.__ptr = static_cast <const __impl *> (__p); > + return __ret; > + } > + constexpr const char *file_name () const { > + return __ptr ? __ptr->_M_file_name : ""; > + } > + constexpr const char *function_name () const { > + return __ptr ? __ptr->_M_function_name : ""; > + } > + constexpr unsigned line () const { > + return __ptr ? __ptr->_M_line : 0; > + } > + constexpr unsigned column () const { > + return __ptr ? __ptr->_M_column : 0; > + } > + }; > +} > + > +constexpr int g(auto...) { > +return std::source_location::current().column(); > +} > + > +constexpr int f() { > +return std::source_location::current().column(); > +} > + > +constexpr int a = g(); > +constexpr int b = f(); > +static_assert (a == b); > --- gcc/testsuite/g++.dg/modules/adhoc-1_b.C.jj 2020-12-22 23:50:17.054972550 +0100 > +++ gcc/testsuite/g++.dg/modules/adhoc-1_b.C 2021-03-22 19:08:19.338344945 +0100 > @@ -6,7 +6,7 @@ void foo () > massivelongnamethatcausesadhoclocationsokeepaddingcharsyourgettheidea (); > } > > -// { dg-regexp "\n\[^\n]*adhoc-1_b.C:6:74: error: no matching function for call to 'massivelongnamethatcausesadhoclocationsokeepaddingcharsyourgettheidea\\(\\)'\n massivelongnamethatcausesadhoclocationsokeepaddingcharsyourgettheidea \\(\\);\n \\^$" } > +// { dg-regexp "\n\[^\n]*adhoc-1_b.C:6:73: error: no matching function for call to 'massivelongnamethatcausesadhoclocationsokeepaddingcharsyourgettheidea\\(\\)'\n massivelongnamethatcausesadhoclocationsokeepaddingcharsyourgettheidea \\(\\);\n ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\\^~$" } > // { dg-regexp "\nIn module bob, imported at \[^\n]*adhoc-1_b.C:3:\n\[^\n]*adhoc-1_a.C:5:12: note: candidate: 'int massivelongnamethatcausesadhoclocationsokeepaddingcharsyourgettheidea@bob\\(int\\)'\n export int massivelongnamethatcausesadhoclocationsokeepaddingcharsyourgettheidea \\(int\\);\n \\^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~$" } > // { dg-regexp "\nIn module bob, imported at \[^\n]*adhoc-1_b.C:3:\n\[^\n]*adhoc-1_a.C:6:188: note: candidate: 'void massivelongnamethatcausesadhoclocationsokeepaddingcharsyourgettheidea@bob\\(float\\)'\n\[ \t]*export void massivelongnamethatcausesadhoclocationsokeepaddingcharsyourgettheidea \\(float\\);\n\[ \t]*\\^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~?$" } > // For some reason dg-regexp inserts a blank line > --- gcc/testsuite/g++.dg/modules/macloc-1_c.C.jj 2020-12-22 23:50:17.061972472 +0100 > +++ gcc/testsuite/g++.dg/modules/macloc-1_c.C 2021-03-22 18:53:29.682029033 +0100 > @@ -8,6 +8,6 @@ void gru () > you (1); > } > > -// { dg-regexp "\[^\n]*macloc-1_c.C:7:8: error: too many arguments to function 'int me@agnes\\(\\)'\nIn module agnes, imported at \[^\n]*macloc-1_b.C:8,\nof module edith, imported at \[^\n]*macloc-1_c.C:3:\n\[^\n]*macloc-1_a.C:11:12: note: declared here\n\[^\n]*macloc-1_a.C:8:20: note: in definition of macro 'BOB'\n" } > +// { dg-regexp "\[^\n]*macloc-1_c.C:7:6: error: too many arguments to function 'int me@agnes\\(\\)'\nIn module agnes, imported at \[^\n]*macloc-1_b.C:8,\nof module edith, imported at \[^\n]*macloc-1_c.C:3:\n\[^\n]*macloc-1_a.C:11:12: note: declared here\n\[^\n]*macloc-1_a.C:8:20: note: in definition of macro 'BOB'\n" } > > -// { dg-regexp "\[^\n]*macloc-1_c.C:8:9: error: too many arguments to function 'int you@agnes\\(\\)'\nIn module agnes, imported at \[^\n]*macloc-1_b.C:8,\nof module edith, imported at \[^\n]*macloc-1_c.C:3:\n\[^\n]*macloc-1_a.C:12:14: note: declared here\n\[^\n]*macloc-1_a.C:9:22: note: in definition of macro 'KEVIN'\n" } > +// { dg-regexp "\[^\n]*macloc-1_c.C:8:7: error: too many arguments to function 'int you@agnes\\(\\)'\nIn module agnes, imported at \[^\n]*macloc-1_b.C:8,\nof module edith, imported at \[^\n]*macloc-1_c.C:3:\n\[^\n]*macloc-1_a.C:12:14: note: declared here\n\[^\n]*macloc-1_a.C:9:22: note: in definition of macro 'KEVIN'\n" } > --- gcc/testsuite/g++.dg/modules/macloc-1_d.C.jj 2020-12-22 23:50:17.061972472 +0100 > +++ gcc/testsuite/g++.dg/modules/macloc-1_d.C 2021-03-22 18:53:57.817722777 +0100 > @@ -9,5 +9,5 @@ void margo () > gru (2); > } > > -// { dg-regexp "\[^\n]*macloc-1_d.C:8:8: error: too many arguments to function 'int me@agnes\\(\\)'\nIn module agnes, imported at \[^\n]*macloc-1_d.C:4:\n\[^\n]*macloc-1_a.C:11:12: note: declared here\n\[^\n]*macloc-1_a.C:8:20: note: in definition of macro 'BOB'\n" } > -// { dg-regexp "\[^\n]*macloc-1_d.C:9:9: error: too many arguments to function 'void gru@edith\\(\\)'\nIn module edith, imported at \[^\n]*macloc-1_d.C:3:\n\[^\n]*macloc-1_b.C:10:20: note: declared here\n\[^\n]*macloc-1_b.C:6:19: note: in definition of macro 'STUART'\n" } > +// { dg-regexp "\[^\n]*macloc-1_d.C:8:6: error: too many arguments to function 'int me@agnes\\(\\)'\nIn module agnes, imported at \[^\n]*macloc-1_d.C:4:\n\[^\n]*macloc-1_a.C:11:12: note: declared here\n\[^\n]*macloc-1_a.C:8:20: note: in definition of macro 'BOB'\n" } > +// { dg-regexp "\[^\n]*macloc-1_d.C:9:7: error: too many arguments to function 'void gru@edith\\(\\)'\nIn module edith, imported at \[^\n]*macloc-1_d.C:3:\n\[^\n]*macloc-1_b.C:10:20: note: declared here\n\[^\n]*macloc-1_b.C:6:19: note: in definition of macro 'STUART'\n" } > --- gcc/testsuite/g++.dg/plugin/diagnostic-test-expressions-1.C.jj 2020-01-14 20:02:46.923607737 +0100 > +++ gcc/testsuite/g++.dg/plugin/diagnostic-test-expressions-1.C 2021-03-22 19:05:54.528921226 +0100 > @@ -900,7 +900,7 @@ void test_methods () > ((base *)1)->priv (); // { dg-error " is private " } > /* { dg-begin-multiline-output "" } > ((base *)1)->priv (); > - ^ > + ~~~~~~~~~~~~~~~~~~^~ > { dg-end-multiline-output "" } > { dg-begin-multiline-output "" } > int priv (); > --- libstdc++-v3/testsuite/18_support/source_location/consteval.cc.jj 2021-01-05 00:13:58.354296528 +0100 > +++ libstdc++-v3/testsuite/18_support/source_location/consteval.cc 2021-03-22 22:17:46.427025787 +0100 > @@ -75,43 +75,43 @@ int main () > using namespace std::string_view_literals; > > static_assert (std::source_location::current ().line () == __LINE__); > - static_assert (std::source_location::current ().column () == 49); > + static_assert (std::source_location::current ().column () == 48); > > > constexpr std::string_view main_sl_fn_name(main_sl.function_name()); > constexpr std::string_view main_sl_fi_name(main_sl.file_name()); > static_assert(main_sl.line() == main_sl_line); > - // closing paren of call > - static_assert(main_sl.column() == 74); > + // opening paren of call > + static_assert(main_sl.column() == 73); > static_assert(main_sl_fn_name.ends_with("main()"sv)); > static_assert(main_sl_fi_name.ends_with("consteval.cc"sv)); > > constexpr std::string_view f_arg_sl_fn_name(f_arg_sl.function_name()); > constexpr std::string_view f_arg_sl_fi_name(f_arg_sl.file_name()); > static_assert(f_arg_sl.line() == f_arg_sl_line); > - // closing paren of call > - static_assert(f_arg_sl.column() == 74); > + // opening paren of call > + static_assert(f_arg_sl.column() == 73); > static_assert(f_arg_sl_fn_name.ends_with("main()"sv)); > static_assert(f_arg_sl_fi_name.ends_with("consteval.cc"sv)); > > constexpr std::string_view g_sl_fn_name(g_sl.function_name()); > constexpr std::string_view g_sl_fi_name(g_sl.file_name()); > static_assert(g_sl.line() == g_sl_line); > - static_assert(g_sl.column() == 58); // closing paren of call > + static_assert(g_sl.column() == 57); // opening paren of call > static_assert(g_sl_fn_name.ends_with("g()"sv)); > static_assert(g_sl_fi_name.ends_with("consteval.cc"sv)); > > constexpr std::string_view h_sl_fn_name(h_sl.function_name()); > constexpr std::string_view h_sl_fi_name(h_sl.file_name()); > static_assert(h_sl.line() == 23); > - static_assert(h_sl.column() == 58); // closing paren of call > + static_assert(h_sl.column() == 57); // opening paren of call > static_assert(h_sl_fn_name.ends_with("h()"sv)); > static_assert(h_sl_fi_name.ends_with("srcloc.h"sv)); > > constexpr std::string_view member_main_sl_fn_name(member_main_sl.member.function_name()); > constexpr std::string_view member_main_sl_fi_name(member_main_sl.member.file_name()); > static_assert(member_main_sl.member.line() == main_sl_line); > - static_assert(member_main_sl.member.column() == 74); > + static_assert(member_main_sl.member.column() == 73); > static_assert(member_main_sl_fn_name.ends_with("main()"sv)); > static_assert(member_main_sl_fi_name.ends_with("consteval.cc"sv)); > > @@ -138,8 +138,8 @@ int main () > constexpr std::string_view f_sl_fi_name(f_sl.file_name()); > constexpr std::string_view f_sl_fn_name(f_sl.function_name()); > static_assert(f_sl.line() == f_sl_line); > - // closing paren of call > - static_assert(f_sl.column() == 43); > + // opening paren of call > + static_assert(f_sl.column() == 42); > static_assert(f_sl_fn_name.ends_with("main()"sv)); > static_assert(f_sl_fi_name.ends_with("consteval.cc"sv)); > > --- libstdc++-v3/testsuite/18_support/source_location/1.cc.jj 2021-01-05 00:13:58.354296528 +0100 > +++ libstdc++-v3/testsuite/18_support/source_location/1.cc 2021-03-22 22:19:16.624026315 +0100 > @@ -87,37 +87,37 @@ int main () > std::string_view main_sl_fn_name(main_sl.function_name()); > std::string_view main_sl_fi_name(main_sl.file_name()); > VERIFY(main_sl.line() == main_sl_line); > - // closing paren of call > - VERIFY(main_sl.column() == 64); > + // opening paren of call > + VERIFY(main_sl.column() == 63); > VERIFY(main_sl_fn_name.ends_with("main()"sv)); > VERIFY(main_sl_fi_name.ends_with("1.cc"sv)); > > std::string_view f_arg_sl_fn_name(f_arg_sl.function_name()); > std::string_view f_arg_sl_fi_name(f_arg_sl.file_name()); > VERIFY(f_arg_sl.line() == f_arg_sl_line); > - // closing paren of call > - VERIFY(f_arg_sl.column() == 64); > + // opening paren of call > + VERIFY(f_arg_sl.column() == 63); > VERIFY(f_arg_sl_fn_name.ends_with("main()"sv)); > VERIFY(f_arg_sl_fi_name.ends_with("1.cc"sv)); > > std::string_view g_sl_fn_name(g_sl.function_name()); > std::string_view g_sl_fi_name(g_sl.file_name()); > VERIFY(g_sl.line() == g_sl_line); > - VERIFY(g_sl.column() == 58); // closing paren of call > + VERIFY(g_sl.column() == 57); // opening paren of call > VERIFY(g_sl_fn_name.ends_with("g()"sv)); > VERIFY(g_sl_fi_name.ends_with("1.cc"sv)); > > std::string_view h_sl_fn_name(h_sl.function_name()); > std::string_view h_sl_fi_name(h_sl.file_name()); > VERIFY(h_sl.line() == 23); > - VERIFY(h_sl.column() == 58); // closing paren of call > + VERIFY(h_sl.column() == 57); // opening paren of call > VERIFY(h_sl_fn_name.ends_with("h()"sv)); > VERIFY(h_sl_fi_name.ends_with("srcloc.h"sv)); > > std::string_view member_main_sl_fn_name(member_main_sl.member.function_name()); > std::string_view member_main_sl_fi_name(member_main_sl.member.file_name()); > VERIFY(member_main_sl.member.line() == main_sl_line); > - VERIFY(member_main_sl.member.column() == 64); > + VERIFY(member_main_sl.member.column() == 63); > VERIFY(member_main_sl_fn_name.ends_with("main()"sv)); > VERIFY(member_main_sl_fi_name.ends_with("1.cc"sv)); > > @@ -144,8 +144,8 @@ int main () > std::string_view f_sl_fi_name(f_sl.file_name()); > std::string_view f_sl_fn_name(f_sl.function_name()); > VERIFY(f_sl.line() == f_sl_line); > - // closing paren of call > - VERIFY(f_sl.column() == 33); > + // opening paren of call > + VERIFY(f_sl.column() == 32); > VERIFY(f_sl_fn_name.ends_with("main()"sv)); > VERIFY(f_sl_fi_name.ends_with("1.cc"sv)); > > > Jakub >
--- gcc/cp/parser.c.jj 2021-03-19 10:14:37.449724617 +0100 +++ gcc/cp/parser.c 2021-03-19 17:35:11.216322995 +0100 @@ -7564,6 +7564,7 @@ cp_parser_postfix_expression (cp_parser tsubst_flags_t complain = complain_flags (decltype_p); vec<tree, va_gc> *args; location_t close_paren_loc = UNKNOWN_LOCATION; + location_t combined_loc = UNKNOWN_LOCATION; is_member_access = false; @@ -7669,6 +7670,20 @@ cp_parser_postfix_expression (cp_parser } } + /* Temporarily set input_location to the combined location + with call expression range, as e.g. build_out_target_exprs + called from convert_default_arg relies on input_location, + so updating it only when the call is fully built results + in inconsistencies between location handling in templates + and outside of templates. */ + if (close_paren_loc != UNKNOWN_LOCATION) + combined_loc = make_location (token->location, start_loc, + close_paren_loc); + auto cleanup + = make_temp_override (input_location, + combined_loc != UNKNOWN_LOCATION + ? combined_loc : input_location); + if (TREE_CODE (postfix_expression) == COMPONENT_REF) { tree instance = TREE_OPERAND (postfix_expression, 0); @@ -7726,12 +7741,7 @@ cp_parser_postfix_expression (cp_parser complain); if (close_paren_loc != UNKNOWN_LOCATION) - { - location_t combined_loc = make_location (token->location, - start_loc, - close_paren_loc); - postfix_expression.set_location (combined_loc); - } + postfix_expression.set_location (combined_loc); /* The POSTFIX_EXPRESSION is certainly no longer an id. */ idk = CP_ID_KIND_NONE; --- gcc/testsuite/g++.dg/concepts/diagnostic2.C.jj 2020-08-24 21:41:17.644520408 +0200 +++ gcc/testsuite/g++.dg/concepts/diagnostic2.C 2021-03-22 19:04:59.947515357 +0100 @@ -25,6 +25,6 @@ baz() bar<int>(); // { dg-error "no match" } /* { dg-begin-multiline-output "" } bar<int>(); - ^ + ~~~~~~~~^~ { dg-end-multiline-output "" } */ } --- gcc/testsuite/g++.dg/cpp1y/builtin_location.C.jj 2020-01-14 20:02:46.771610014 +0100 +++ gcc/testsuite/g++.dg/cpp1y/builtin_location.C 2021-03-22 17:27:59.121756869 +0100 @@ -103,10 +103,10 @@ A (0 == __builtin_strcmp (f3, FILE_3)); #define FILE_4 "next_file_name.another_suffix" #line 1 "foobar" constexpr const char* f4 = this_file - ( #line 1 FILE_4 - ) + ( #line 1 "foobar" + ) ; A (0 == __builtin_strcmp (f4, FILE_4)); @@ -167,9 +167,9 @@ A (n5 == 9); // of the function call. #line 1 constexpr int n6 = this_line - ( #line 99 - ) + ( #line 1 + ) ; A (n6 == 99); --- gcc/testsuite/g++.dg/cpp2a/srcloc1.C.jj 2020-12-04 16:02:57.300153753 +0100 +++ gcc/testsuite/g++.dg/cpp2a/srcloc1.C 2021-03-20 00:30:14.245469602 +0100 @@ -80,7 +80,7 @@ constexpr source_location s2 = baz <1> ( const source_location *p1 = &s1; const source_location *p2 = &s2; static_assert (source_location::current ().line () == __LINE__); -static_assert (source_location::current ().column () == 42); +static_assert (source_location::current ().column () == 41); constexpr bool quux () @@ -106,7 +106,7 @@ quux () return false; if (line1 != line2) return false; - if (column != 33) + if (column != 32) return false; return true; } --- gcc/testsuite/g++.dg/cpp2a/srcloc2.C.jj 2020-12-04 16:02:57.300153753 +0100 +++ gcc/testsuite/g++.dg/cpp2a/srcloc2.C 2021-03-20 00:30:14.245469602 +0100 @@ -84,7 +84,7 @@ const source_location *p1 = &s1; const source_location *p2 = &s2; static_assert (source_location::current ().line () == __LINE__); -static_assert (source_location::current ().column () == 42); +static_assert (source_location::current ().column () == 41); constexpr bool quux () @@ -110,7 +110,7 @@ quux () return false; if (line1 != line2) return false; - if (column != 33) + if (column != 32) return false; return true; } --- gcc/testsuite/g++.dg/cpp2a/srcloc15.C.jj 2020-12-04 16:02:57.300153753 +0100 +++ gcc/testsuite/g++.dg/cpp2a/srcloc15.C 2021-03-20 00:30:14.246469591 +0100 @@ -69,8 +69,8 @@ bar () source_location a = foo (); source_location b = source_location::current (); source_location c = foo (); - // ^ column 28 - // ^ column 49 + // ^ column 27 + // ^ column 48 const source_location *d[3] = { &a, &b, &c }; const char *file1 = __FILE__; const char *function1 = __PRETTY_FUNCTION__; @@ -83,7 +83,7 @@ bar () return false; if (d[j]->line () != line + j + 1) return false; - if (d[j]->column () != (j == 1 ? 49 : 28)) + if (d[j]->column () != (j == 1 ? 48 : 27)) return false; } --- gcc/testsuite/g++.dg/cpp2a/srcloc16.C.jj 2020-12-03 23:21:57.709534533 +0100 +++ gcc/testsuite/g++.dg/cpp2a/srcloc16.C 2021-03-20 00:30:14.246469591 +0100 @@ -79,10 +79,10 @@ foo () || u.u.line () + 1 != v.line () || s.a.column () != 18 || s.b.column () != 18 - || s.c.column () != 50 + || s.c.column () != 49 || t.u.column () != 21 || u.u.column () != 13 - || v.column () != 49) + || v.column () != 48) return false; return true; } --- gcc/testsuite/g++.dg/cpp2a/srcloc19.C.jj 2021-03-20 00:30:14.246469591 +0100 +++ gcc/testsuite/g++.dg/cpp2a/srcloc19.C 2021-03-20 00:30:14.246469591 +0100 @@ -0,0 +1,44 @@ +// PR c++/99672 +// { dg-do compile { target c++20 } } + +namespace std { + struct source_location { + struct __impl { + const char *_M_file_name; + const char *_M_function_name; + unsigned int _M_line, _M_column; + }; + const __impl *__ptr; + constexpr source_location () : __ptr (nullptr) {} + static consteval source_location + current (const void *__p = __builtin_source_location ()) { + source_location __ret; + __ret.__ptr = static_cast <const __impl *> (__p); + return __ret; + } + constexpr const char *file_name () const { + return __ptr ? __ptr->_M_file_name : ""; + } + constexpr const char *function_name () const { + return __ptr ? __ptr->_M_function_name : ""; + } + constexpr unsigned line () const { + return __ptr ? __ptr->_M_line : 0; + } + constexpr unsigned column () const { + return __ptr ? __ptr->_M_column : 0; + } + }; +} + +constexpr int g(auto...) { +return std::source_location::current().column(); +} + +constexpr int f() { +return std::source_location::current().column(); +} + +constexpr int a = g(); +constexpr int b = f(); +static_assert (a == b); --- gcc/testsuite/g++.dg/modules/adhoc-1_b.C.jj 2020-12-22 23:50:17.054972550 +0100 +++ gcc/testsuite/g++.dg/modules/adhoc-1_b.C 2021-03-22 19:08:19.338344945 +0100 @@ -6,7 +6,7 @@ void foo () massivelongnamethatcausesadhoclocationsokeepaddingcharsyourgettheidea (); } -// { dg-regexp "\n\[^\n]*adhoc-1_b.C:6:74: error: no matching function for call to 'massivelongnamethatcausesadhoclocationsokeepaddingcharsyourgettheidea\\(\\)'\n massivelongnamethatcausesadhoclocationsokeepaddingcharsyourgettheidea \\(\\);\n \\^$" } +// { dg-regexp "\n\[^\n]*adhoc-1_b.C:6:73: error: no matching function for call to 'massivelongnamethatcausesadhoclocationsokeepaddingcharsyourgettheidea\\(\\)'\n massivelongnamethatcausesadhoclocationsokeepaddingcharsyourgettheidea \\(\\);\n ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\\^~$" } // { dg-regexp "\nIn module bob, imported at \[^\n]*adhoc-1_b.C:3:\n\[^\n]*adhoc-1_a.C:5:12: note: candidate: 'int massivelongnamethatcausesadhoclocationsokeepaddingcharsyourgettheidea@bob\\(int\\)'\n export int massivelongnamethatcausesadhoclocationsokeepaddingcharsyourgettheidea \\(int\\);\n \\^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~$" } // { dg-regexp "\nIn module bob, imported at \[^\n]*adhoc-1_b.C:3:\n\[^\n]*adhoc-1_a.C:6:188: note: candidate: 'void massivelongnamethatcausesadhoclocationsokeepaddingcharsyourgettheidea@bob\\(float\\)'\n\[ \t]*export void massivelongnamethatcausesadhoclocationsokeepaddingcharsyourgettheidea \\(float\\);\n\[ \t]*\\^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~?$" } // For some reason dg-regexp inserts a blank line --- gcc/testsuite/g++.dg/modules/macloc-1_c.C.jj 2020-12-22 23:50:17.061972472 +0100 +++ gcc/testsuite/g++.dg/modules/macloc-1_c.C 2021-03-22 18:53:29.682029033 +0100 @@ -8,6 +8,6 @@ void gru () you (1); } -// { dg-regexp "\[^\n]*macloc-1_c.C:7:8: error: too many arguments to function 'int me@agnes\\(\\)'\nIn module agnes, imported at \[^\n]*macloc-1_b.C:8,\nof module edith, imported at \[^\n]*macloc-1_c.C:3:\n\[^\n]*macloc-1_a.C:11:12: note: declared here\n\[^\n]*macloc-1_a.C:8:20: note: in definition of macro 'BOB'\n" } +// { dg-regexp "\[^\n]*macloc-1_c.C:7:6: error: too many arguments to function 'int me@agnes\\(\\)'\nIn module agnes, imported at \[^\n]*macloc-1_b.C:8,\nof module edith, imported at \[^\n]*macloc-1_c.C:3:\n\[^\n]*macloc-1_a.C:11:12: note: declared here\n\[^\n]*macloc-1_a.C:8:20: note: in definition of macro 'BOB'\n" } -// { dg-regexp "\[^\n]*macloc-1_c.C:8:9: error: too many arguments to function 'int you@agnes\\(\\)'\nIn module agnes, imported at \[^\n]*macloc-1_b.C:8,\nof module edith, imported at \[^\n]*macloc-1_c.C:3:\n\[^\n]*macloc-1_a.C:12:14: note: declared here\n\[^\n]*macloc-1_a.C:9:22: note: in definition of macro 'KEVIN'\n" } +// { dg-regexp "\[^\n]*macloc-1_c.C:8:7: error: too many arguments to function 'int you@agnes\\(\\)'\nIn module agnes, imported at \[^\n]*macloc-1_b.C:8,\nof module edith, imported at \[^\n]*macloc-1_c.C:3:\n\[^\n]*macloc-1_a.C:12:14: note: declared here\n\[^\n]*macloc-1_a.C:9:22: note: in definition of macro 'KEVIN'\n" } --- gcc/testsuite/g++.dg/modules/macloc-1_d.C.jj 2020-12-22 23:50:17.061972472 +0100 +++ gcc/testsuite/g++.dg/modules/macloc-1_d.C 2021-03-22 18:53:57.817722777 +0100 @@ -9,5 +9,5 @@ void margo () gru (2); } -// { dg-regexp "\[^\n]*macloc-1_d.C:8:8: error: too many arguments to function 'int me@agnes\\(\\)'\nIn module agnes, imported at \[^\n]*macloc-1_d.C:4:\n\[^\n]*macloc-1_a.C:11:12: note: declared here\n\[^\n]*macloc-1_a.C:8:20: note: in definition of macro 'BOB'\n" } -// { dg-regexp "\[^\n]*macloc-1_d.C:9:9: error: too many arguments to function 'void gru@edith\\(\\)'\nIn module edith, imported at \[^\n]*macloc-1_d.C:3:\n\[^\n]*macloc-1_b.C:10:20: note: declared here\n\[^\n]*macloc-1_b.C:6:19: note: in definition of macro 'STUART'\n" } +// { dg-regexp "\[^\n]*macloc-1_d.C:8:6: error: too many arguments to function 'int me@agnes\\(\\)'\nIn module agnes, imported at \[^\n]*macloc-1_d.C:4:\n\[^\n]*macloc-1_a.C:11:12: note: declared here\n\[^\n]*macloc-1_a.C:8:20: note: in definition of macro 'BOB'\n" } +// { dg-regexp "\[^\n]*macloc-1_d.C:9:7: error: too many arguments to function 'void gru@edith\\(\\)'\nIn module edith, imported at \[^\n]*macloc-1_d.C:3:\n\[^\n]*macloc-1_b.C:10:20: note: declared here\n\[^\n]*macloc-1_b.C:6:19: note: in definition of macro 'STUART'\n" } --- gcc/testsuite/g++.dg/plugin/diagnostic-test-expressions-1.C.jj 2020-01-14 20:02:46.923607737 +0100 +++ gcc/testsuite/g++.dg/plugin/diagnostic-test-expressions-1.C 2021-03-22 19:05:54.528921226 +0100 @@ -900,7 +900,7 @@ void test_methods () ((base *)1)->priv (); // { dg-error " is private " } /* { dg-begin-multiline-output "" } ((base *)1)->priv (); - ^ + ~~~~~~~~~~~~~~~~~~^~ { dg-end-multiline-output "" } { dg-begin-multiline-output "" } int priv (); --- libstdc++-v3/testsuite/18_support/source_location/consteval.cc.jj 2021-01-05 00:13:58.354296528 +0100 +++ libstdc++-v3/testsuite/18_support/source_location/consteval.cc 2021-03-22 22:17:46.427025787 +0100 @@ -75,43 +75,43 @@ int main () using namespace std::string_view_literals; static_assert (std::source_location::current ().line () == __LINE__); - static_assert (std::source_location::current ().column () == 49); + static_assert (std::source_location::current ().column () == 48); constexpr std::string_view main_sl_fn_name(main_sl.function_name()); constexpr std::string_view main_sl_fi_name(main_sl.file_name()); static_assert(main_sl.line() == main_sl_line); - // closing paren of call - static_assert(main_sl.column() == 74); + // opening paren of call + static_assert(main_sl.column() == 73); static_assert(main_sl_fn_name.ends_with("main()"sv)); static_assert(main_sl_fi_name.ends_with("consteval.cc"sv)); constexpr std::string_view f_arg_sl_fn_name(f_arg_sl.function_name()); constexpr std::string_view f_arg_sl_fi_name(f_arg_sl.file_name()); static_assert(f_arg_sl.line() == f_arg_sl_line); - // closing paren of call - static_assert(f_arg_sl.column() == 74); + // opening paren of call + static_assert(f_arg_sl.column() == 73); static_assert(f_arg_sl_fn_name.ends_with("main()"sv)); static_assert(f_arg_sl_fi_name.ends_with("consteval.cc"sv)); constexpr std::string_view g_sl_fn_name(g_sl.function_name()); constexpr std::string_view g_sl_fi_name(g_sl.file_name()); static_assert(g_sl.line() == g_sl_line); - static_assert(g_sl.column() == 58); // closing paren of call + static_assert(g_sl.column() == 57); // opening paren of call static_assert(g_sl_fn_name.ends_with("g()"sv)); static_assert(g_sl_fi_name.ends_with("consteval.cc"sv)); constexpr std::string_view h_sl_fn_name(h_sl.function_name()); constexpr std::string_view h_sl_fi_name(h_sl.file_name()); static_assert(h_sl.line() == 23); - static_assert(h_sl.column() == 58); // closing paren of call + static_assert(h_sl.column() == 57); // opening paren of call static_assert(h_sl_fn_name.ends_with("h()"sv)); static_assert(h_sl_fi_name.ends_with("srcloc.h"sv)); constexpr std::string_view member_main_sl_fn_name(member_main_sl.member.function_name()); constexpr std::string_view member_main_sl_fi_name(member_main_sl.member.file_name()); static_assert(member_main_sl.member.line() == main_sl_line); - static_assert(member_main_sl.member.column() == 74); + static_assert(member_main_sl.member.column() == 73); static_assert(member_main_sl_fn_name.ends_with("main()"sv)); static_assert(member_main_sl_fi_name.ends_with("consteval.cc"sv)); @@ -138,8 +138,8 @@ int main () constexpr std::string_view f_sl_fi_name(f_sl.file_name()); constexpr std::string_view f_sl_fn_name(f_sl.function_name()); static_assert(f_sl.line() == f_sl_line); - // closing paren of call - static_assert(f_sl.column() == 43); + // opening paren of call + static_assert(f_sl.column() == 42); static_assert(f_sl_fn_name.ends_with("main()"sv)); static_assert(f_sl_fi_name.ends_with("consteval.cc"sv)); --- libstdc++-v3/testsuite/18_support/source_location/1.cc.jj 2021-01-05 00:13:58.354296528 +0100 +++ libstdc++-v3/testsuite/18_support/source_location/1.cc 2021-03-22 22:19:16.624026315 +0100 @@ -87,37 +87,37 @@ int main () std::string_view main_sl_fn_name(main_sl.function_name()); std::string_view main_sl_fi_name(main_sl.file_name()); VERIFY(main_sl.line() == main_sl_line); - // closing paren of call - VERIFY(main_sl.column() == 64); + // opening paren of call + VERIFY(main_sl.column() == 63); VERIFY(main_sl_fn_name.ends_with("main()"sv)); VERIFY(main_sl_fi_name.ends_with("1.cc"sv)); std::string_view f_arg_sl_fn_name(f_arg_sl.function_name()); std::string_view f_arg_sl_fi_name(f_arg_sl.file_name()); VERIFY(f_arg_sl.line() == f_arg_sl_line); - // closing paren of call - VERIFY(f_arg_sl.column() == 64); + // opening paren of call + VERIFY(f_arg_sl.column() == 63); VERIFY(f_arg_sl_fn_name.ends_with("main()"sv)); VERIFY(f_arg_sl_fi_name.ends_with("1.cc"sv)); std::string_view g_sl_fn_name(g_sl.function_name()); std::string_view g_sl_fi_name(g_sl.file_name()); VERIFY(g_sl.line() == g_sl_line); - VERIFY(g_sl.column() == 58); // closing paren of call + VERIFY(g_sl.column() == 57); // opening paren of call VERIFY(g_sl_fn_name.ends_with("g()"sv)); VERIFY(g_sl_fi_name.ends_with("1.cc"sv)); std::string_view h_sl_fn_name(h_sl.function_name()); std::string_view h_sl_fi_name(h_sl.file_name()); VERIFY(h_sl.line() == 23); - VERIFY(h_sl.column() == 58); // closing paren of call + VERIFY(h_sl.column() == 57); // opening paren of call VERIFY(h_sl_fn_name.ends_with("h()"sv)); VERIFY(h_sl_fi_name.ends_with("srcloc.h"sv)); std::string_view member_main_sl_fn_name(member_main_sl.member.function_name()); std::string_view member_main_sl_fi_name(member_main_sl.member.file_name()); VERIFY(member_main_sl.member.line() == main_sl_line); - VERIFY(member_main_sl.member.column() == 64); + VERIFY(member_main_sl.member.column() == 63); VERIFY(member_main_sl_fn_name.ends_with("main()"sv)); VERIFY(member_main_sl_fi_name.ends_with("1.cc"sv)); @@ -144,8 +144,8 @@ int main () std::string_view f_sl_fi_name(f_sl.file_name()); std::string_view f_sl_fn_name(f_sl.function_name()); VERIFY(f_sl.line() == f_sl_line); - // closing paren of call - VERIFY(f_sl.column() == 33); + // opening paren of call + VERIFY(f_sl.column() == 32); VERIFY(f_sl_fn_name.ends_with("main()"sv)); VERIFY(f_sl_fi_name.ends_with("1.cc"sv));