PR c++/62314: add fixit hint for "expected ';' after class definition"
authorDavid Malcolm <dmalcolm@redhat.com>
Tue, 5 Jul 2016 15:50:54 +0000 (15:50 +0000)
committerDavid Malcolm <dmalcolm@gcc.gnu.org>
Tue, 5 Jul 2016 15:50:54 +0000 (15:50 +0000)
gcc/cp/ChangeLog:
PR c++/62314
* parser.c (cp_parser_class_specifier_1): When reporting
missing semicolons, use a fixit-hint to suggest insertion
of a semicolon immediately after the closing brace,
offsetting the reported column accordingly.

gcc/testsuite/ChangeLog:
PR c++/62314
* gcc/testsuite/g++.dg/parse/error5.C: Update column
number of missing semicolon error.
* g++.dg/pr62314-2.C: New test case.

From-SVN: r238008

gcc/cp/ChangeLog
gcc/cp/parser.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/parse/error5.C
gcc/testsuite/g++.dg/pr62314-2.C [new file with mode: 0644]

index 7da1c55e93efe8414bb3eb4f12d927f17934a4bf..c129b5f7ce6ef908b67f585aee3fc8693b892f77 100644 (file)
@@ -1,3 +1,11 @@
+2016-07-05  David Malcolm  <dmalcolm@redhat.com>
+
+       PR c++/62314
+       * parser.c (cp_parser_class_specifier_1): When reporting
+       missing semicolons, use a fixit-hint to suggest insertion
+       of a semicolon immediately after the closing brace,
+       offsetting the reported column accordingly.
+
 2016-07-04  Jan Beulich  <jbeulich@suse.com>
 
        * lang-specs.h ("@c++-header"): Conditionalize "-o".
index 3e8270e1e6acb0629a494864f1d36a5f0cd1acc3..ef35aa9cfb05bea32683c2812c8cb9f4989ac504 100644 (file)
@@ -21450,17 +21450,30 @@ cp_parser_class_specifier_1 (cp_parser* parser)
        closing brace.  */
     if (closing_brace && TYPE_P (type) && want_semicolon)
       {
+       /* Locate the closing brace.  */
        cp_token_position prev
          = cp_lexer_previous_token_position (parser->lexer);
        cp_token *prev_token = cp_lexer_token_at (parser->lexer, prev);
        location_t loc = prev_token->location;
 
+       /* We want to suggest insertion of a ';' immediately *after* the
+          closing brace, so, if we can, offset the location by 1 column.  */
+       location_t next_loc = loc;
+       if (!linemap_location_from_macro_expansion_p (line_table, loc))
+         next_loc = linemap_position_for_loc_and_offset (line_table, loc, 1);
+
+       rich_location richloc (line_table, next_loc);
+       richloc.add_fixit_insert (next_loc, ";");
+
        if (CLASSTYPE_DECLARED_CLASS (type))
-         error_at (loc, "expected %<;%> after class definition");
+         error_at_rich_loc (&richloc,
+                            "expected %<;%> after class definition");
        else if (TREE_CODE (type) == RECORD_TYPE)
-         error_at (loc, "expected %<;%> after struct definition");
+         error_at_rich_loc (&richloc,
+                            "expected %<;%> after struct definition");
        else if (TREE_CODE (type) == UNION_TYPE)
-         error_at (loc, "expected %<;%> after union definition");
+         error_at_rich_loc (&richloc,
+                            "expected %<;%> after union definition");
        else
          gcc_unreachable ();
 
index 944dbb66160fd2eb089a7ee1ea229b25a53b3b2d..f86ee90ec5e0dc4c0134e45f1c1dad3312f2e7ce 100644 (file)
@@ -1,3 +1,10 @@
+2016-07-05  David Malcolm  <dmalcolm@redhat.com>
+
+       PR c++/62314
+       * gcc/testsuite/g++.dg/parse/error5.C: Update column
+       number of missing semicolon error.
+       * g++.dg/pr62314-2.C: New test case.
+
 2016-07-05  Alessandro Fanfarillo  <fanfarillo.gcc@gmail.com>
 
        * gfortran.dg/coarray_stat_function.f90: New test.
index eb1f9c730a839f9a22e9771a29c5714c26a46320..d14a47664b85dfbe1871234ebee238de41b74132 100644 (file)
@@ -13,7 +13,7 @@ class Foo { int foo() return 0; } };
 // need make cp_parser_error() report more accurate column numbers.
 // { dg-error "30:expected '\{' at end of input" "brace" { target *-*-* } 4 }
 
-// { dg-error "33:expected ';' after class definition" "semicolon" {target *-*-* } 4 }
+// { dg-error "34:expected ';' after class definition" "semicolon" {target *-*-* } 4 }
 
 // { dg-error "35:expected declaration before '\}' token" "declaration" {target *-*-* } 4 }
 
diff --git a/gcc/testsuite/g++.dg/pr62314-2.C b/gcc/testsuite/g++.dg/pr62314-2.C
new file mode 100644 (file)
index 0000000..deb0cb7
--- /dev/null
@@ -0,0 +1,22 @@
+// { dg-options "-fdiagnostics-show-caret" }
+
+template<class T>
+class a {} // { dg-error "11: expected .;. after class definition" }
+class temp {};
+a<temp> b;
+struct b {
+} // { dg-error "2: expected .;. after struct definition" }
+
+/* Verify that we emit fixit hints.  */
+
+/* { dg-begin-multiline-output "" }
+ class a {}
+           ^
+           ;
+   { dg-end-multiline-output "" } */
+
+/* { dg-begin-multiline-output "" }
+ }
+  ^
+  ;
+   { dg-end-multiline-output "" } */