diff mbox

C++ FE: Show both locations in string literal concatenation error

Message ID 1450198321-5367-1-git-send-email-dmalcolm@redhat.com
State New
Headers show

Commit Message

David Malcolm Dec. 15, 2015, 4:52 p.m. UTC
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 mbox

Patch

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 "" } */