@@ -5949,12 +5949,13 @@ catenate_strings (const char *lhs, const char *rhs_start, int rhs_size)
return result;
}
-/* Issue the error given by GMSGID, indicating that it occurred before
- TOKEN, which had the associated VALUE. */
+/* Issue the error given by GMSGID at RICHLOC, indicating that it occurred
+ before TOKEN, which had the associated VALUE. */
void
c_parse_error (const char *gmsgid, enum cpp_ttype token_type,
- tree value, unsigned char token_flags)
+ tree value, unsigned char token_flags,
+ rich_location *richloc)
{
#define catenate_messages(M1, M2) catenate_strings ((M1), (M2), sizeof (M2))
@@ -5995,7 +5996,7 @@ c_parse_error (const char *gmsgid, enum cpp_ttype token_type,
else
message = catenate_messages (gmsgid, " before %s'\\x%x'");
- error (message, prefix, val);
+ error_at_rich_loc (richloc, message, prefix, val);
free (message);
message = NULL;
}
@@ -6023,7 +6024,7 @@ c_parse_error (const char *gmsgid, enum cpp_ttype token_type,
else if (token_type == CPP_NAME)
{
message = catenate_messages (gmsgid, " before %qE");
- error (message, value);
+ error_at_rich_loc (richloc, message, value);
free (message);
message = NULL;
}
@@ -6036,16 +6037,16 @@ c_parse_error (const char *gmsgid, enum cpp_ttype token_type,
else if (token_type < N_TTYPES)
{
message = catenate_messages (gmsgid, " before %qs token");
- error (message, cpp_type2name (token_type, token_flags));
+ error_at_rich_loc (richloc, message, cpp_type2name (token_type, token_flags));
free (message);
message = NULL;
}
else
- error (gmsgid);
+ error_at_rich_loc (richloc, gmsgid);
if (message)
{
- error (message);
+ error_at_rich_loc (richloc, message);
free (message);
}
#undef catenate_messages
@@ -1124,7 +1124,8 @@ extern void builtin_define_with_int_value (const char *, HOST_WIDE_INT);
extern void builtin_define_type_sizeof (const char *, tree);
extern void c_stddef_cpp_builtins (void);
extern void fe_file_change (const line_map_ordinary *);
-extern void c_parse_error (const char *, enum cpp_ttype, tree, unsigned char);
+extern void c_parse_error (const char *, enum cpp_ttype, tree, unsigned char,
+ rich_location *richloc);
/* In c-ppoutput.c */
extern void init_pp_output (FILE *);
new file mode 100644
@@ -0,0 +1,33 @@
+/* { dg-options "-fdiagnostics-show-caret" } */
+
+/* Verify that the C/C++ frontends show the pertinent opening symbol when
+ a closing symbol is missing. */
+
+/* Verify that, when they are on the same line, that the opening symbol is
+ shown as a secondary range within the main diagnostic. */
+
+void test_static_assert_same_line (void)
+{
+ _Static_assert(sizeof(int) >= sizeof(char), "msg"; /* { dg-error "expected '\\)' before ';' token" } */
+ /* { dg-begin-multiline-output "" }
+ _Static_assert(sizeof(int) >= sizeof(char), "msg";
+ ~ ^
+ { dg-end-multiline-output "" } */
+}
+
+/* Verify that, when they are on different lines, that the opening symbol is
+ shown via a secondary diagnostic. */
+
+void test_static_assert_different_line (void)
+{
+ _Static_assert(sizeof(int) >= sizeof(char), /* { dg-message "to match this '\\('" } */
+ "msg"; /* { dg-error "expected '\\)' before ';' token" } */
+ /* { dg-begin-multiline-output "" }
+ "msg";
+ ^
+ { dg-end-multiline-output "" } */
+ /* { dg-begin-multiline-output "" }
+ _Static_assert(sizeof(int) >= sizeof(char),
+ ^
+ { dg-end-multiline-output "" } */
+}
new file mode 100644
@@ -0,0 +1,50 @@
+/* { dg-options "-fdiagnostics-show-caret" } */
+
+extern int foo (void);
+extern int bar (void);
+
+int missing_close_paren_in_switch (int i)
+{
+ switch (i /* { dg-message "10: to match this '\\('" } */
+ { /* { dg-error "5: expected '\\)' before '.' token" } */
+ /* { dg-begin-multiline-output "" }
+ {
+ ^
+ { dg-end-multiline-output "" } */
+ /* { dg-begin-multiline-output "" }
+ switch (i
+ ^
+ { dg-end-multiline-output "" } */
+
+ case 0:
+ return 5;
+ default:
+ return i;
+ }
+} /* { dg-error "1: expected" } */
+ /* { dg-begin-multiline-output "" }
+ }
+ ^
+ { dg-end-multiline-output "" } */
+
+void missing_close_paren_in_if (void)
+{
+ if (foo () /* { dg-line start_of_if } */
+ && bar ()
+ { /* { dg-error "5: expected '\\)' before '.' token" } */
+ /* { dg-begin-multiline-output "" }
+ {
+ ^
+ { dg-end-multiline-output "" } */
+ /* { dg-message "6: to match this '\\('" "" { target *-*-* } start_of_if } */
+ /* { dg-begin-multiline-output "" }
+ if (foo ()
+ ^
+ { dg-end-multiline-output "" } */
+ }
+
+} /* { dg-error "1: expected" } */
+ /* { dg-begin-multiline-output "" }
+ }
+ ^
+ { dg-end-multiline-output "" } */