OK for trunk? (assuming the rest is approved) gcc/c-family/ChangeLog: * c-common.c (c_parse_error): Add rich_location * param, using it rather implicitly using input_location. * c-common.h (c_parse_error): Add rich_location * param.
gcc/testsuite/ChangeLog: * c-c++-common/missing-close-symbol.c: New test case. * c-c++-common/missing-symbol.c: New test case. --- gcc/c-family/c-common.c | 17 ++++---- gcc/c-family/c-common.h | 3 +- gcc/testsuite/c-c++-common/missing-close-symbol.c | 33 +++++++++++++++ gcc/testsuite/c-c++-common/missing-symbol.c | 50 +++++++++++++++++++++++ 4 files changed, 94 insertions(+), 9 deletions(-) create mode 100644 gcc/testsuite/c-c++-common/missing-close-symbol.c create mode 100644 gcc/testsuite/c-c++-common/missing-symbol.c diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c index b4217f3..b168cb5 100644 --- a/gcc/c-family/c-common.c +++ b/gcc/c-family/c-common.c @@ -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 diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h index 7e7efb2..de92701 100644 --- a/gcc/c-family/c-common.h +++ b/gcc/c-family/c-common.h @@ -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 *); diff --git a/gcc/testsuite/c-c++-common/missing-close-symbol.c b/gcc/testsuite/c-c++-common/missing-close-symbol.c new file mode 100644 index 0000000..85b96f28 --- /dev/null +++ b/gcc/testsuite/c-c++-common/missing-close-symbol.c @@ -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 "" } */ +} diff --git a/gcc/testsuite/c-c++-common/missing-symbol.c b/gcc/testsuite/c-c++-common/missing-symbol.c new file mode 100644 index 0000000..33a501b --- /dev/null +++ b/gcc/testsuite/c-c++-common/missing-symbol.c @@ -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 "" } */ -- 1.8.5.3