We can use rich_location and the new diagnostic_show_locus to print *both* locations when complaining about a bogus string concatenation in the C++ FE, giving e.g.:
test.C:3:24: error: unsupported non-standard concatenation of string literals const void *s = u8"a" u"b"; ~~~~~ ^~~~ Successfully bootstrapped®rtested on x86_64-pc-linux-gnu OK for trunk for gcc 6? (an earlier version of this was posted as part of: "[PATCH 10/22] C++ FE: Use token ranges for various diagnostics" https://gcc.gnu.org/ml/gcc-patches/2015-09/msg00730.html though the implementation has changed slightly) gcc/cp/ChangeLog: * parser.c (cp_parser_string_literal): Convert non-standard concatenation error to directly use a rich_location, and use that to add the location of the first literal to the diagnostic. gcc/testsuite/ChangeLog: * g++.dg/diagnostic/string-literal-concat.C: New test case. --- gcc/cp/parser.c | 16 +++++++++++----- gcc/testsuite/g++.dg/diagnostic/string-literal-concat.C | 13 +++++++++++++ 2 files changed, 24 insertions(+), 5 deletions(-) create mode 100644 gcc/testsuite/g++.dg/diagnostic/string-literal-concat.C diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index a420cf1..5247a5e 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -3815,13 +3815,12 @@ cp_parser_string_literal (cp_parser *parser, bool translate, bool wide_ok, } else { - location_t last_tok_loc; + location_t last_tok_loc = tok->location; gcc_obstack_init (&str_ob); count = 0; do { - last_tok_loc = tok->location; cp_lexer_consume_token (parser->lexer); count++; str.text = (const unsigned char *)TREE_STRING_POINTER (string_tree); @@ -3853,13 +3852,20 @@ cp_parser_string_literal (cp_parser *parser, bool translate, bool wide_ok, if (type == CPP_STRING) type = curr_type; else if (curr_type != CPP_STRING) - error_at (tok->location, - "unsupported non-standard concatenation " - "of string literals"); + { + rich_location rich_loc (line_table, tok->location); + rich_loc.add_range (last_tok_loc, get_finish (last_tok_loc), + false); + error_at_rich_loc (&rich_loc, + "unsupported non-standard concatenation " + "of string literals"); + } } obstack_grow (&str_ob, &str, sizeof (cpp_string)); + last_tok_loc = tok->location; + tok = cp_lexer_peek_token (parser->lexer); if (cpp_userdef_string_p (tok->type)) { diff --git a/gcc/testsuite/g++.dg/diagnostic/string-literal-concat.C b/gcc/testsuite/g++.dg/diagnostic/string-literal-concat.C new file mode 100644 index 0000000..2819b25 --- /dev/null +++ b/gcc/testsuite/g++.dg/diagnostic/string-literal-concat.C @@ -0,0 +1,13 @@ +/* { dg-options "-fdiagnostics-show-caret -std=c++11" } */ + +const void *s = u8"a" u"b"; // { dg-error "non-standard concatenation" } +/* { dg-begin-multiline-output "" } + const void *s = u8"a" u"b"; + ~~~~~ ^~~~ + { dg-end-multiline-output "" } */ + +const void *s2 = u"a" u"b" u8"c"; // { dg-error "non-standard concatenation" } +/* { dg-begin-multiline-output "" } + const void *s2 = u"a" u"b" u8"c"; + ~~~~ ^~~~~ + { dg-end-multiline-output "" } */ -- 1.8.5.3