diff mbox

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

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

Commit Message

David Malcolm June 17, 2016, 7:29 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";
                 ~~~~~  ^~~~

Earlier versions of this were posted as part of
  https://gcc.gnu.org/ml/gcc-patches/2015-09/msg00730.html
    "[PATCH 10/22] C++ FE: Use token ranges for various diagnostics"
and:
  https://gcc.gnu.org/ml/gcc-patches/2015-12/msg01497.html
though the implementation has changed slightly.

Successfully bootstrapped&regrtested on x86_64-pc-linux-gnu;
adds 7 PASS results to g++.sum.

OK for trunk?

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                                    | 15 +++++++++-----
 .../g++.dg/diagnostic/string-literal-concat.C      | 23 ++++++++++++++++++++++
 2 files changed, 33 insertions(+), 5 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/diagnostic/string-literal-concat.C

Comments

Jason Merrill June 18, 2016, 4:40 p.m. UTC | #1
OK.

Jason
diff mbox

Patch

diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 632b25f..e1e9271 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -3893,13 +3893,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);
@@ -3931,13 +3930,19 @@  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, 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..4ede799
--- /dev/null
+++ b/gcc/testsuite/g++.dg/diagnostic/string-literal-concat.C
@@ -0,0 +1,23 @@ 
+/* { dg-options "-fdiagnostics-show-caret -std=c++11" } */
+
+const void *s = u8"a"  u"b";  // { dg-error "24: 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 "30: non-standard concatenation" }
+/* { dg-begin-multiline-output "" }
+ const void *s2 = u"a"  u"b"  u8"c";
+                        ~~~~  ^~~~~
+  { dg-end-multiline-output "" } */
+
+#define TEST_U8_LITERAL u8"a"
+
+const void *s3 = TEST_U8_LITERAL u8"b";
+
+const void *s4 = TEST_U8_LITERAL u"b"; // { dg-error "34: non-standard concatenation" }
+/* { dg-begin-multiline-output "" }
+ const void *s4 = TEST_U8_LITERAL u"b";
+                                  ^~~~
+  { dg-end-multiline-output "" } */