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&regrtested 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

Reply via email to