From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 77930 invoked by alias); 3 Jul 2017 18:04:14 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 77894 invoked by uid 89); 3 Jul 2017 18:04:11 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-26.9 required=5.0 tests=BAYES_00,GIT_PATCH_0,GIT_PATCH_1,GIT_PATCH_2,GIT_PATCH_3,RP_MATCHES_RCVD,SPF_HELO_PASS autolearn=ham version=3.3.2 spammy=adl, sleeping, Once, 74 X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Mon, 03 Jul 2017 18:04:05 +0000 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 5ADFAC058ED5 for ; Mon, 3 Jul 2017 18:04:03 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 5ADFAC058ED5 Authentication-Results: ext-mx08.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx08.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=dmalcolm@redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com 5ADFAC058ED5 Received: from c64.redhat.com (ovpn-112-19.phx2.redhat.com [10.3.112.19]) by smtp.corp.redhat.com (Postfix) with ESMTP id 29CE962929; Mon, 3 Jul 2017 18:04:01 +0000 (UTC) From: David Malcolm To: gcc-patches@gcc.gnu.org Cc: David Malcolm Subject: [PATCH] C/C++: add fix-it hints for various missing symbols Date: Mon, 03 Jul 2017 18:04:00 -0000 Message-Id: <1499107059-28855-1-git-send-email-dmalcolm@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-IsSubscribed: yes X-SW-Source: 2017-07/txt/msg00135.txt.bz2 This patch improves our C/C++ frontends' handling of missing symbols, by making c_parser_require and cp_parser_require use "better" locations for the diagnostic, and insert fix-it hints, under certain circumstances (see the comments in the patch for full details). For example, for this code with a missing semicolon: $ cat test.c int missing_semicolon (void) { return 42 } trunk currently emits: test.c:4:1: error: expected ‘;’ before ‘}’ token } ^ This patch adds a fix-it hint for the missing semicolon, and puts the error at the location of the missing semicolon, printing the followup token as a secondary location: test.c:3:12: error: expected ‘;’ before ‘}’ token return 42 ^ ; } ~ More examples can be seen in the test cases. For reference, clang prints the following: test.c:3:12: error: expected ';' after return statement return 42 ^ ; i.e. describing what syntactic thing came before, which I think is likely to be more meaningful to the user. clang can also print notes about matching opening symbols e.g. the note here: missing-symbol-2.c:25:22: error: expected ']' const char test [42; ^ missing-symbol-2.c:25:19: note: to match this '[' const char test [42; ^ which, although somewhat redundant for this example, seems much more useful if there's non-trivial nesting of constructs, or more than a few lines separating the open/close symbols (e.g. showing a stray "namespace {" that the user forgot to close). I'd like to implement both of these ideas as followups, but in the meantime, is the fix-it hint patch OK for trunk? (successfully bootstrapped & regrtested on x86_64-pc-linux-gnu) gcc/c-family/ChangeLog: * c-common.c (c_parse_error): Add RICHLOC param, and use it rather than implicitly using input_location. (enum missing_token_insertion_kind): New enum. (get_missing_token_insertion_kind): New function. (maybe_suggest_missing_token_insertion): New function. * c-common.h (c_parse_error): Add RICHLOC param. (maybe_suggest_missing_token_insertion): New decl. gcc/c/ChangeLog: * c-parser.c (struct c_parser): Add "previous_token_loc" field. (c_parser_consume_token): Set parser->previous_token_loc. (c_parser_error): Rename to... (c_parser_error_richloc): ...this, making static, and adding "richloc" parameter, passing it to the c_parse_error call, rather than calling c_parser_set_source_position_from_token. (c_parser_error): Reintroduce, reimplementing in terms of the above. (c_parser_require): Add "type_is_unique" param. Use c_parser_error_richloc rather than c_parser_error, calling maybe_suggest_missing_token_insertion. (c_parser_parms_list_declarator): Override default value of new "type_is_unique" param to c_parser_require. (c_parser_asm_statement): Likewise. * c-parser.h (c_parser_require): Add "type_is_unique" param, defaulting to true. gcc/cp/ChangeLog: * parser.c (cp_parser_error): Add rich_location to call to c_parse_error. (get_required_cpp_ttype): New function. (cp_parser_required_error): Remove calls to cp_parser_error, instead setting a non-NULL gmsgid, and handling it if set by calling c_parse_error, potentially with a fix-it hint. gcc/testsuite/ChangeLog: * c-c++-common/cilk-plus/AN/parser_errors.c: Update expected output to reflect changes to reported locations of missing symbols. * c-c++-common/cilk-plus/AN/parser_errors2.c: Likewise. * c-c++-common/cilk-plus/AN/parser_errors3.c: Likewise. * c-c++-common/cilk-plus/AN/pr61191.c: Likewise. * c-c++-common/gomp/pr63326.c: Likewise. * c-c++-common/missing-symbol.c: New test case. * g++.dg/cpp1y/digit-sep-neg.C: Update expected output to reflect changes to reported locations of missing symbols. * g++.dg/cpp1y/pr65202.C: Likewise. * g++.dg/other/do1.C: Likewise. * g++.dg/missing-symbol-2.C: New test case. * g++.dg/parse/error11.C: Update expected output to reflect changes to reported locations of missing symbols. * g++.dg/parse/pragma2.C: Likewise. * g++.dg/template/error11.C: Likewise. * gcc.dg/missing-symbol-2.c: New test case. * gcc.dg/missing-symbol-3.c: New test case. * gcc.dg/noncompile/940112-1.c: Update expected output to reflect changes to reported locations of missing symbols. * gcc.dg/noncompile/971104-1.c: Likewise. * obj-c++.dg/exceptions-6.mm: Likewise. * obj-c++.dg/pr48187.mm: Likewise. * objc.dg/exceptions-6.m: Likewise. --- gcc/c-family/c-common.c | 176 +++++++++++++- gcc/c-family/c-common.h | 7 +- gcc/c/c-parser.c | 55 ++++- gcc/c/c-parser.h | 2 +- gcc/cp/parser.c | 254 +++++++++++++-------- .../c-c++-common/cilk-plus/AN/parser_errors.c | 4 +- .../c-c++-common/cilk-plus/AN/parser_errors2.c | 3 +- .../c-c++-common/cilk-plus/AN/parser_errors3.c | 3 +- gcc/testsuite/c-c++-common/cilk-plus/AN/pr61191.c | 3 +- gcc/testsuite/c-c++-common/gomp/pr63326.c | 22 +- gcc/testsuite/c-c++-common/missing-symbol.c | 34 +++ gcc/testsuite/g++.dg/cpp1y/digit-sep-neg.C | 4 +- gcc/testsuite/g++.dg/cpp1y/pr65202.C | 4 +- gcc/testsuite/g++.dg/missing-symbol-2.C | 58 +++++ gcc/testsuite/g++.dg/other/do1.C | 4 +- gcc/testsuite/g++.dg/parse/error11.C | 2 +- gcc/testsuite/g++.dg/parse/pragma2.C | 4 +- gcc/testsuite/g++.dg/template/error11.C | 2 +- gcc/testsuite/gcc.dg/missing-symbol-2.c | 71 ++++++ gcc/testsuite/gcc.dg/missing-symbol-3.c | 50 ++++ gcc/testsuite/gcc.dg/noncompile/940112-1.c | 4 +- gcc/testsuite/gcc.dg/noncompile/971104-1.c | 4 +- gcc/testsuite/obj-c++.dg/exceptions-6.mm | 6 +- gcc/testsuite/obj-c++.dg/pr48187.mm | 8 +- gcc/testsuite/objc.dg/exceptions-6.m | 4 +- 25 files changed, 629 insertions(+), 159 deletions(-) create mode 100644 gcc/testsuite/c-c++-common/missing-symbol.c create mode 100644 gcc/testsuite/g++.dg/missing-symbol-2.C create mode 100644 gcc/testsuite/gcc.dg/missing-symbol-2.c create mode 100644 gcc/testsuite/gcc.dg/missing-symbol-3.c diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c index 4395e51..f75a869 100644 --- a/gcc/c-family/c-common.c +++ b/gcc/c-family/c-common.c @@ -5945,12 +5945,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)) @@ -5991,7 +5992,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; } @@ -6019,7 +6020,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; } @@ -6032,16 +6033,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 @@ -7996,4 +7997,163 @@ c_flt_eval_method (bool maybe_c11_only_p) return c_ts18661_flt_eval_method (); } +/* An enum for get_missing_token_insertion_kind for describing the best + place to insert a missing token, if there is one. */ + +enum missing_token_insertion_kind +{ + MTIK_IMPOSSIBLE, + MTIK_INSERT_BEFORE_NEXT, + MTIK_INSERT_AFTER_PREV +}; + +/* Given a missing token of TYPE, determine if it is reasonable to + emit a fix-it hint suggesting the insertion of the token, and, + if so, where the token should be inserted relative to other tokens. + + For example, it only makes sense to do this for values of TYPE that + are symbols. + + Some symbols should go before the next token, e.g. in: + if flag) + we want to insert the missing '(' immediately before "flag", + giving: + if (flag) + rather than: + if( flag) + These use MTIK_INSERT_BEFORE_NEXT. + + Other symbols should go after the previous token, e.g. in: + if (flag + do_something (); + we want to insert the missing ')' immediately after the "flag", + giving: + if (flag) + do_something (); + rather than: + if (flag + )do_something (); + These use MTIK_INSERT_AFTER_PREV. */ + +static enum missing_token_insertion_kind +get_missing_token_insertion_kind (enum cpp_ttype type) +{ + switch (type) + { + /* Insert missing "opening" brackets immediately + before the next token. */ + case CPP_OPEN_SQUARE: + case CPP_OPEN_PAREN: + return MTIK_INSERT_BEFORE_NEXT; + + /* Insert other missing symbols immediately after + the previous token. */ + case CPP_CLOSE_PAREN: + case CPP_CLOSE_SQUARE: + case CPP_SEMICOLON: + case CPP_COMMA: + case CPP_COLON: + return MTIK_INSERT_AFTER_PREV; + + /* Other kinds of token don't get fix-it hints. */ + default: + return MTIK_IMPOSSIBLE; + } +} + +/* Given RICHLOC, a location for a diagnostic describing a missing token + of kind TOKEN_TYPE, potentially add a fix-it hint suggesting the + insertion of the token. + + The location of the attemped fix-it hint depends on TOKEN_TYPE: + it will either be: + (a) immediately after PREV_TOKEN_LOC, or + + (b) immediately before the primary location within RICHLOC (taken to + be that of the token following where the token was expected). + + If we manage to add a fix-it hint, then the location of the + fix-it hint is likely to be more useful as the primary location + of the diagnostic than that of the following token, so we swap + these locations. + + For example, given this bogus code: + 123456789012345678901234567890 + 1 | int missing_semicolon (void) + 2 | { + 3 | return 42 + 4 | } + + we will emit: + + "expected ';' before '}'" + + RICHLOC's primary location is at the closing brace, so before "swapping" + we would emit the error at line 4 column 1: + + 123456789012345678901234567890 + 3 | return 42 |< fix-it hint emitted for this line + | ; | + 4 | } |< "expected ';' before '}'" emitted at this line + | ^ | + + It's more useful for the location of the diagnostic to be at the + fix-it hint, so we swap the locations, so the primary location + is at the fix-it hint, with the old primary location inserted + as a secondary location, giving this, with the error at line 3 + column 12: + + 123456789012345678901234567890 + 3 | return 42 |< "expected ';' before '}'" emitted at this line, + | ^ | with fix-it hint + 4 | ; | + | } |< secondary range emitted here + | ~ |. */ + +void +maybe_suggest_missing_token_insertion (rich_location *richloc, + enum cpp_ttype token_type, + location_t prev_token_loc) +{ + gcc_assert (richloc); + + enum missing_token_insertion_kind mtik + = get_missing_token_insertion_kind (token_type); + + switch (mtik) + { + default: + gcc_unreachable (); + break; + + case MTIK_IMPOSSIBLE: + return; + + case MTIK_INSERT_BEFORE_NEXT: + /* Attempt to add the fix-it hint before the primary location + of RICHLOC. */ + richloc->add_fixit_insert_before (cpp_type2name (token_type, 0)); + break; + + case MTIK_INSERT_AFTER_PREV: + /* Attempt to add the fix-it hint after PREV_TOKEN_LOC. */ + richloc->add_fixit_insert_after (prev_token_loc, + cpp_type2name (token_type, 0)); + break; + } + + /* If we were successful, use the fix-it hint's location as the + primary location within RICHLOC, adding the old primary location + back as a secondary location. */ + if (!richloc->seen_impossible_fixit_p ()) + { + fixit_hint *hint = richloc->get_last_fixit_hint (); + location_t hint_loc = hint->get_start_loc (); + location_t old_loc = richloc->get_loc (); + + richloc->set_range (line_table, 0, hint_loc, true); + richloc->add_range (old_loc, false); + } +} + #include "gt-c-family-c-common.h" diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h index 1748c19..f5fd6ae 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 *); @@ -1554,6 +1555,10 @@ excess_precision_mode_join (enum flt_eval_method, enum flt_eval_method); extern int c_flt_eval_method (bool ts18661_p); extern void add_no_sanitize_value (tree node, unsigned int flags); +extern void maybe_suggest_missing_token_insertion (rich_location *richloc, + enum cpp_ttype token_type, + location_t prev_token_loc); + #if CHECKING_P namespace selftest { extern void c_format_c_tests (void); diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c index 6f954f2..11f061f 100644 --- a/gcc/c/c-parser.c +++ b/gcc/c/c-parser.c @@ -206,6 +206,9 @@ struct GTY(()) c_parser { /* Buffer to hold all the tokens from parsing the vector attribute for the SIMD-enabled functions (formerly known as elemental functions). */ vec *cilk_simd_fn_tokens; + + /* Location of the most-recently consumed token. */ + location_t previous_token_loc; }; /* Return a pointer to the Nth token in PARSERs tokens_buf. */ @@ -770,6 +773,7 @@ c_parser_consume_token (c_parser *parser) gcc_assert (parser->tokens[0].type != CPP_EOF); gcc_assert (!parser->in_pragma || parser->tokens[0].type != CPP_PRAGMA_EOL); gcc_assert (parser->error || parser->tokens[0].type != CPP_PRAGMA); + parser->previous_token_loc = parser->tokens[0].location; if (parser->tokens != &parser->tokens_buf[0]) parser->tokens++; else if (parser->tokens_avail == 2) @@ -850,14 +854,17 @@ c_parser_peek_conflict_marker (c_parser *parser, enum cpp_ttype tok1_kind, MESSAGE (specified by the caller) is usually of the form "expected OTHER-TOKEN". + Use RICHLOC as the location of the diagnostic. + Do not issue a diagnostic if still recovering from an error. ??? This is taken from the C++ parser, but building up messages in this way is not i18n-friendly and some other approach should be used. */ -void -c_parser_error (c_parser *parser, const char *gmsgid) +static void +c_parser_error_richloc (c_parser *parser, const char *gmsgid, + rich_location *richloc) { c_token *token = c_parser_peek_token (parser); if (parser->error) @@ -879,9 +886,6 @@ c_parser_error (c_parser *parser, const char *gmsgid) } } - /* This diagnostic makes more sense if it is tagged to the line of - the token we just peeked at. */ - c_parser_set_source_position_from_token (token); c_parse_error (gmsgid, /* Because c_parse_error does not understand CPP_KEYWORD, keywords are treated like @@ -891,18 +895,39 @@ c_parser_error (c_parser *parser, const char *gmsgid) token, we need to pass 0 here and we will not get the source spelling of some tokens but rather the canonical spelling. */ - token->value, /*flags=*/0); + token->value, /*flags=*/0, richloc); +} + +/* As c_parser_error_richloc, but issue the message at the + location of PARSER's next token, or at input_location + if the next token is EOF. */ + +void +c_parser_error (c_parser *parser, const char *gmsgid) +{ + c_token *token = c_parser_peek_token (parser); + c_parser_set_source_position_from_token (token); + rich_location richloc (line_table, input_location); + c_parser_error_richloc (parser, gmsgid, &richloc); } /* If the next token is of the indicated TYPE, consume it. Otherwise, issue the error MSGID. If MSGID is NULL then a message has already been produced and no message will be produced this time. Returns - true if found, false otherwise. */ + true if found, false otherwise. + + If TYPE_IS_UNIQUE is true (the default) then msgid describes exactly + one type (e.g. "expected %<)%>") and thus it may be reasonable to + attempt to generate a fix-it hint for the problem. + Otherwise msgid describes multiple token types (e.g. + "expected %<;%>, %<,%> or %<)%>"), and thus we shouldn't attempt to + generate a fix-it hint. */ bool c_parser_require (c_parser *parser, enum cpp_ttype type, - const char *msgid) + const char *msgid, + bool type_is_unique) { if (c_parser_next_token_is (parser, type)) { @@ -911,7 +936,14 @@ c_parser_require (c_parser *parser, } else { - c_parser_error (parser, msgid); + rich_location richloc (line_table, + c_parser_peek_token (parser)->location); + /* Potentially supply a fix-it hint, suggesting to add the + missing token immediately after the *previous* token. */ + if (!parser->error && type_is_unique) + maybe_suggest_missing_token_insertion (&richloc, type, + parser->previous_token_loc); + c_parser_error_richloc (parser, msgid, &richloc); return false; } } @@ -3798,7 +3830,7 @@ c_parser_parms_list_declarator (c_parser *parser, tree attrs, tree expr) return get_parm_info (false, expr); } if (!c_parser_require (parser, CPP_COMMA, - "expected %<;%>, %<,%> or %<)%>")) + "expected %<;%>, %<,%> or %<)%>", false)) { c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); return NULL; @@ -6177,7 +6209,8 @@ c_parser_asm_statement (c_parser *parser) if (!c_parser_require (parser, CPP_COLON, is_goto ? G_("expected %<:%>") - : G_("expected %<:%> or %<)%>"))) + : G_("expected %<:%> or %<)%>"), + is_goto)) goto error_close_paren; /* Once past any colon, we're no longer a simple asm. */ diff --git a/gcc/c/c-parser.h b/gcc/c/c-parser.h index 1e344c4..70b318f 100644 --- a/gcc/c/c-parser.h +++ b/gcc/c/c-parser.h @@ -136,7 +136,7 @@ extern c_token * c_parser_peek_token (c_parser *parser); extern c_token * c_parser_peek_2nd_token (c_parser *parser); extern c_token * c_parser_peek_nth_token (c_parser *parser, unsigned int n); extern bool c_parser_require (c_parser *parser, enum cpp_ttype type, - const char *msgid); + const char *msgid, bool type_is_unique=true); extern void c_parser_error (c_parser *parser, const char *gmsgid); extern void c_parser_consume_token (c_parser *parser); extern void c_parser_skip_until_found (c_parser *parser, enum cpp_ttype type, diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 1ee3ffe..d605aef 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -2804,12 +2804,13 @@ cp_parser_error (cp_parser* parser, const char* gmsgid) } } + rich_location richloc (line_table, input_location); c_parse_error (gmsgid, /* Because c_parser_error does not understand CPP_KEYWORD, keywords are treated like identifiers. */ (token->type == CPP_KEYWORD ? CPP_NAME : token->type), - token->u.value, token->flags); + token->u.value, token->flags, &richloc); } } @@ -27758,6 +27759,39 @@ cp_parser_friend_p (const cp_decl_specifier_seq *decl_specifiers) return decl_spec_seq_has_spec_p (decl_specifiers, ds_friend); } +/* Attempt to convert TOKEN_DESC from a required_token to an + enum cpp_ttype, returning CPP_EOF if there is no good conversion. */ + +static enum cpp_ttype +get_required_cpp_ttype (required_token token_desc) +{ + switch (token_desc) + { + case RT_SEMICOLON: + return CPP_SEMICOLON; + case RT_OPEN_PAREN: + return CPP_OPEN_PAREN; + case RT_CLOSE_BRACE: + return CPP_CLOSE_BRACE; + case RT_OPEN_BRACE: + return CPP_OPEN_BRACE; + case RT_CLOSE_SQUARE: + return CPP_CLOSE_SQUARE; + case RT_OPEN_SQUARE: + return CPP_OPEN_SQUARE; + case RT_COMMA: + return CPP_COMMA; + case RT_COLON: + return CPP_COLON; + case RT_CLOSE_PAREN: + return CPP_CLOSE_PAREN; + + default: + /* Use CPP_EOF as a "no completions possible" code. */ + return CPP_EOF; + } +} + /* Issue an error message indicating that TOKEN_DESC was expected. If KEYWORD is true, it indicated this function is called by cp_parser_require_keword and the required token can only be @@ -27768,163 +27802,185 @@ cp_parser_required_error (cp_parser *parser, required_token token_desc, bool keyword) { + if (cp_parser_simulate_error (parser)) + return; + + const char *gmsgid = NULL; switch (token_desc) { case RT_NEW: - cp_parser_error (parser, "expected %"); - return; + gmsgid = G_("expected %"); + break; case RT_DELETE: - cp_parser_error (parser, "expected %"); - return; + gmsgid = G_("expected %"); + break; case RT_RETURN: - cp_parser_error (parser, "expected %"); - return; + gmsgid = G_("expected %"); + break; case RT_WHILE: - cp_parser_error (parser, "expected %"); - return; + gmsgid = G_("expected %"); + break; case RT_EXTERN: - cp_parser_error (parser, "expected %"); - return; + gmsgid = G_("expected %"); + break; case RT_STATIC_ASSERT: - cp_parser_error (parser, "expected %"); - return; + gmsgid = G_("expected %"); + break; case RT_DECLTYPE: - cp_parser_error (parser, "expected %"); - return; + gmsgid = G_("expected %"); + break; case RT_OPERATOR: - cp_parser_error (parser, "expected %"); - return; + gmsgid = G_("expected %"); + break; case RT_CLASS: - cp_parser_error (parser, "expected %"); - return; + gmsgid = G_("expected %"); + break; case RT_TEMPLATE: - cp_parser_error (parser, "expected %"); - return; + gmsgid = G_("expected %"); + break; case RT_NAMESPACE: - cp_parser_error (parser, "expected %"); - return; + gmsgid = G_("expected %"); + break; case RT_USING: - cp_parser_error (parser, "expected %"); - return; + gmsgid = G_("expected %"); + break; case RT_ASM: - cp_parser_error (parser, "expected %"); - return; + gmsgid = G_("expected %"); + break; case RT_TRY: - cp_parser_error (parser, "expected %"); - return; + gmsgid = G_("expected %"); + break; case RT_CATCH: - cp_parser_error (parser, "expected %"); - return; + gmsgid = G_("expected %"); + break; case RT_THROW: - cp_parser_error (parser, "expected %"); - return; + gmsgid = G_("expected %"); + break; case RT_LABEL: - cp_parser_error (parser, "expected %<__label__%>"); - return; + gmsgid = G_("expected %<__label__%>"); + break; case RT_AT_TRY: - cp_parser_error (parser, "expected %<@try%>"); - return; + gmsgid = G_("expected %<@try%>"); + break; case RT_AT_SYNCHRONIZED: - cp_parser_error (parser, "expected %<@synchronized%>"); - return; + gmsgid = G_("expected %<@synchronized%>"); + break; case RT_AT_THROW: - cp_parser_error (parser, "expected %<@throw%>"); - return; + gmsgid = G_("expected %<@throw%>"); + break; case RT_TRANSACTION_ATOMIC: - cp_parser_error (parser, "expected %<__transaction_atomic%>"); - return; + gmsgid = G_("expected %<__transaction_atomic%>"); + break; case RT_TRANSACTION_RELAXED: - cp_parser_error (parser, "expected %<__transaction_relaxed%>"); - return; + gmsgid = G_("expected %<__transaction_relaxed%>"); + break; default: break; } - if (!keyword) + + if (!gmsgid && !keyword) { switch (token_desc) { case RT_SEMICOLON: - cp_parser_error (parser, "expected %<;%>"); - return; + gmsgid = G_("expected %<;%>"); + break; case RT_OPEN_PAREN: - cp_parser_error (parser, "expected %<(%>"); - return; + gmsgid = G_("expected %<(%>"); + break; case RT_CLOSE_BRACE: - cp_parser_error (parser, "expected %<}%>"); - return; + gmsgid = G_("expected %<}%>"); + break; case RT_OPEN_BRACE: - cp_parser_error (parser, "expected %<{%>"); - return; + gmsgid = G_("expected %<{%>"); + break; case RT_CLOSE_SQUARE: - cp_parser_error (parser, "expected %<]%>"); - return; + gmsgid = G_("expected %<]%>"); + break; case RT_OPEN_SQUARE: - cp_parser_error (parser, "expected %<[%>"); - return; + gmsgid = G_("expected %<[%>"); + break; case RT_COMMA: - cp_parser_error (parser, "expected %<,%>"); - return; + gmsgid = G_("expected %<,%>"); + break; case RT_SCOPE: - cp_parser_error (parser, "expected %<::%>"); - return; + gmsgid = G_("expected %<::%>"); + break; case RT_LESS: - cp_parser_error (parser, "expected %<<%>"); - return; + gmsgid = G_("expected %<<%>"); + break; case RT_GREATER: - cp_parser_error (parser, "expected %<>%>"); - return; + gmsgid = G_("expected %<>%>"); + break; case RT_EQ: - cp_parser_error (parser, "expected %<=%>"); - return; + gmsgid = G_("expected %<=%>"); + break; case RT_ELLIPSIS: - cp_parser_error (parser, "expected %<...%>"); - return; + gmsgid = G_("expected %<...%>"); + break; case RT_MULT: - cp_parser_error (parser, "expected %<*%>"); - return; + gmsgid = G_("expected %<*%>"); + break; case RT_COMPL: - cp_parser_error (parser, "expected %<~%>"); - return; + gmsgid = G_("expected %<~%>"); + break; case RT_COLON: - cp_parser_error (parser, "expected %<:%>"); - return; + gmsgid = G_("expected %<:%>"); + break; case RT_COLON_SCOPE: - cp_parser_error (parser, "expected %<:%> or %<::%>"); - return; + gmsgid = G_("expected %<:%> or %<::%>"); + break; case RT_CLOSE_PAREN: - cp_parser_error (parser, "expected %<)%>"); - return; + gmsgid = G_("expected %<)%>"); + break; case RT_COMMA_CLOSE_PAREN: - cp_parser_error (parser, "expected %<,%> or %<)%>"); - return; + gmsgid = G_("expected %<,%> or %<)%>"); + break; case RT_PRAGMA_EOL: - cp_parser_error (parser, "expected end of line"); - return; + gmsgid = G_("expected end of line"); + break; case RT_NAME: - cp_parser_error (parser, "expected identifier"); - return; + gmsgid = G_("expected identifier"); + break; case RT_SELECT: - cp_parser_error (parser, "expected selection-statement"); - return; + gmsgid = G_("expected selection-statement"); + break; case RT_ITERATION: - cp_parser_error (parser, "expected iteration-statement"); - return; + gmsgid = G_("expected iteration-statement"); + break; case RT_JUMP: - cp_parser_error (parser, "expected jump-statement"); - return; + gmsgid = G_("expected jump-statement"); + break; case RT_CLASS_KEY: - cp_parser_error (parser, "expected class-key"); - return; + gmsgid = G_("expected class-key"); + break; case RT_CLASS_TYPENAME_TEMPLATE: - cp_parser_error (parser, - "expected %, %, or %"); - return; + gmsgid = G_("expected %, %, or %"); + break; default: gcc_unreachable (); } } - else - gcc_unreachable (); + + if (gmsgid) + { + /* Emulate rest of cp_parser_error. */ + cp_token *token = cp_lexer_peek_token (parser->lexer); + cp_lexer_set_source_position_from_token (token); + + rich_location richloc (line_table, input_location); + + /* Potentially supply a fix-it hint, suggesting to add the + missing token immediately after the *previous* token. */ + enum cpp_ttype ttype = get_required_cpp_ttype (token_desc); + location_t prev_token_loc + = cp_lexer_previous_token (parser->lexer)->location; + maybe_suggest_missing_token_insertion (&richloc, ttype, prev_token_loc); + + c_parse_error (gmsgid, + (token->type == CPP_KEYWORD ? CPP_NAME : token->type), + token->u.value, token->flags, &richloc); + } } diff --git a/gcc/testsuite/c-c++-common/cilk-plus/AN/parser_errors.c b/gcc/testsuite/c-c++-common/cilk-plus/AN/parser_errors.c index 18816e0..fd4fe54 100644 --- a/gcc/testsuite/c-c++-common/cilk-plus/AN/parser_errors.c +++ b/gcc/testsuite/c-c++-common/cilk-plus/AN/parser_errors.c @@ -7,5 +7,5 @@ int main (void) array2[:] = array2[: ; /* { dg-error "expected ']'" } */ - return 0; -} /* { dg-error "expected ';' before" "" { target c } } */ + return 0; /* { dg-error "expected ';' before" "" { target c } } */ +} diff --git a/gcc/testsuite/c-c++-common/cilk-plus/AN/parser_errors2.c b/gcc/testsuite/c-c++-common/cilk-plus/AN/parser_errors2.c index 2bb9134..d003d7c 100644 --- a/gcc/testsuite/c-c++-common/cilk-plus/AN/parser_errors2.c +++ b/gcc/testsuite/c-c++-common/cilk-plus/AN/parser_errors2.c @@ -7,6 +7,7 @@ int main (void) array2[:] = array2[1:2:] ; /* { dg-error "expected expression before" "" { target c } } */ /* { dg-error "expected primary-expression before" "" { target c++ } .-1 } */ + /* { dg-error "expected ';' before" "" { target c } .-2 } */ - return 0; /* { dg-error "expected ';' before" "" { target c } } */ + return 0; } diff --git a/gcc/testsuite/c-c++-common/cilk-plus/AN/parser_errors3.c b/gcc/testsuite/c-c++-common/cilk-plus/AN/parser_errors3.c index 9270007..14256e9 100644 --- a/gcc/testsuite/c-c++-common/cilk-plus/AN/parser_errors3.c +++ b/gcc/testsuite/c-c++-common/cilk-plus/AN/parser_errors3.c @@ -7,6 +7,7 @@ int main (void) array2[:] = array2[1: :] ; /* { dg-error "expected expression before" "" { target c } } */ /* { dg-error "expected primary-expression before" "" { target c++ } .-1 } */ + /* { dg-error "expected ';' before" "" { target c } .-2 } */ - return 0; /* { dg-error "expected ';' before" "" { target c } } */ + return 0; } diff --git a/gcc/testsuite/c-c++-common/cilk-plus/AN/pr61191.c b/gcc/testsuite/c-c++-common/cilk-plus/AN/pr61191.c index a9a9d66..8c32ad9 100644 --- a/gcc/testsuite/c-c++-common/cilk-plus/AN/pr61191.c +++ b/gcc/testsuite/c-c++-common/cilk-plus/AN/pr61191.c @@ -7,4 +7,5 @@ double f(double * A, double * B) return __sec_reduce_add((B[0:500])(; /* { dg-error "called object" "" { target c } } */ /* { dg-error "expected expression before ';' token" "" { target c } .-1 } */ /* { dg-error "expected primary-expression before ';' token" "" { target c++ } .-2 } */ -} /* { dg-error "expected" "" { target c } } */ +/* { dg-error "expected" "" { target c } .-3 } */ +} diff --git a/gcc/testsuite/c-c++-common/gomp/pr63326.c b/gcc/testsuite/c-c++-common/gomp/pr63326.c index e319f49..3e62723 100644 --- a/gcc/testsuite/c-c++-common/gomp/pr63326.c +++ b/gcc/testsuite/c-c++-common/gomp/pr63326.c @@ -156,34 +156,34 @@ f4 (int x) { do #pragma omp barrier /* { dg-error "may only be used in compound statements" } */ - while (0); + while (0); /* { dg-error "before" "" { target c++ } } */ } /* { dg-error "before" "" { target c++ } } */ { do #pragma omp flush /* { dg-error "may only be used in compound statements" } */ - while (0); + while (0); /* { dg-error "before" "" { target c++ } } */ } /* { dg-error "before" "" { target c++ } } */ { do #pragma omp taskwait /* { dg-error "may only be used in compound statements" } */ - while (0); + while (0); /* { dg-error "before" "" { target c++ } } */ } /* { dg-error "before" "" { target c++ } } */ { do #pragma omp taskyield /* { dg-error "may only be used in compound statements" } */ - while (0); + while (0); /* { dg-error "before" "" { target c++ } } */ } /* { dg-error "before" "" { target c++ } } */ #pragma omp parallel { do #pragma omp cancel parallel /* { dg-error "may only be used in compound statements" } */ - while (0); + while (0); /* { dg-error "before" "" { target c++ } } */ } /* { dg-error "before" "" { target c++ } } */ #pragma omp parallel { do #pragma omp cancellation point parallel /* { dg-error "may only be used in compound statements" } */ - while (0); + while (0); /* { dg-error "before" "" { target c++ } } */ } /* { dg-error "before" "" { target c++ } } */ #pragma omp for ordered(1) for (i = 0; i < 16; i++) @@ -191,28 +191,28 @@ f4 (int x) { do #pragma omp ordered depend(source) /* { dg-error "may only be used in compound statements" } */ - while (0); + while (0); /* { dg-error "before" "" { target c++ } } */ } /* { dg-error "before" "" { target c++ } } */ { do #pragma omp ordered depend(sink: i-1) /* { dg-error "may only be used in compound statements" } */ - while (0); + while (0); /* { dg-error "before" "" { target c++ } } */ } /* { dg-error "before" "" { target c++ } } */ } { do #pragma omp target enter data map(to:i) /* { dg-error "may only be used in compound statements" } */ - while (0); + while (0); /* { dg-error "before" "" { target c++ } } */ } /* { dg-error "before" "" { target c++ } } */ { do #pragma omp target update to(i) /* { dg-error "may only be used in compound statements" } */ - while (0); + while (0); /* { dg-error "before" "" { target c++ } } */ } /* { dg-error "before" "" { target c++ } } */ { do #pragma omp target exit data map(from:i) /* { dg-error "may only be used in compound statements" } */ - while (0); + while (0); /* { dg-error "before" "" { target c++ } } */ } /* { dg-error "before" "" { target c++ } } */ } 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..d056516 --- /dev/null +++ b/gcc/testsuite/c-c++-common/missing-symbol.c @@ -0,0 +1,34 @@ +/* { dg-options "-fdiagnostics-show-caret" } */ + +extern int foo (void); +extern int bar (void); + +void missing_close_paren (void) +{ + if (foo () + && bar () /* { dg-error "16: expected '\\)' before '.' token" } */ + { + /* { dg-begin-multiline-output "" } + && bar () + ^ + ) + { + ~ + { dg-end-multiline-output "" } */ + } +} /* { dg-error "1: expected" } */ + /* { dg-begin-multiline-output "" } + } + ^ + { dg-end-multiline-output "" } */ + + +int missing_colon_in_ternary (int flag) +{ + return flag ? 42 0; /* { dg-error "expected ':' before numeric constant" } */ + /* { dg-begin-multiline-output "" } + return flag ? 42 0; + ^~ + : + { dg-end-multiline-output "" } */ +} diff --git a/gcc/testsuite/g++.dg/cpp1y/digit-sep-neg.C b/gcc/testsuite/g++.dg/cpp1y/digit-sep-neg.C index 833fab7..727e74e 100644 --- a/gcc/testsuite/g++.dg/cpp1y/digit-sep-neg.C +++ b/gcc/testsuite/g++.dg/cpp1y/digit-sep-neg.C @@ -26,5 +26,5 @@ main() } // { dg-error "exponent has no digits" "exponent has no digits" { target *-*-* } 21 } -// { dg-error "expected ';' before" "expected ';' before" { target *-*-* } 14 } -// { dg-error "expected ';' before" "expected ';' before" { target *-*-* } 25 } +// { dg-error "expected ';' before" "expected ';' before" { target *-*-* } 13 } +// { dg-error "expected ';' before" "expected ';' before" { target *-*-* } 24 } diff --git a/gcc/testsuite/g++.dg/cpp1y/pr65202.C b/gcc/testsuite/g++.dg/cpp1y/pr65202.C index 602b264..7ce4895 100644 --- a/gcc/testsuite/g++.dg/cpp1y/pr65202.C +++ b/gcc/testsuite/g++.dg/cpp1y/pr65202.C @@ -22,5 +22,5 @@ struct bar; int main() { foo f; - adl::swap(f, f) -} // { dg-error "" } + adl::swap(f, f) // { dg-error "expected ';'" } +} // { dg-error "expected '.'" "expected end of namespace" } diff --git a/gcc/testsuite/g++.dg/missing-symbol-2.C b/gcc/testsuite/g++.dg/missing-symbol-2.C new file mode 100644 index 0000000..4a119f8 --- /dev/null +++ b/gcc/testsuite/g++.dg/missing-symbol-2.C @@ -0,0 +1,58 @@ +/* { dg-options "-fdiagnostics-show-caret" } */ + +extern int foo (void); + +void missing_open_paren (void) +{ + if foo ()) /* { dg-error "expected '\\(' before 'foo'" } */ + { + } + /* { dg-begin-multiline-output "" } + if foo ()) + ^~~ + ( + { dg-end-multiline-output "" } */ +} + + +void missing_close_square (void) +{ + const char test [42; /* { dg-error "22: expected ']' before ';' token" } */ + /* { dg-begin-multiline-output "" } + const char test [42; + ^ + ] + { dg-end-multiline-output "" } */ +} + +int missing_semicolon (void) +{ + return 42 /* { dg-error "expected ';'" } */ +} +/* { dg-begin-multiline-output "" } + return 42 + ^ + ; + } + ~ + { dg-end-multiline-output "" } */ + + +int missing_colon_in_switch (int val) +{ + switch (val) + { + case 42 /* { dg-error "expected ':' before 'return'" } */ + return 42; + /* { dg-begin-multiline-output "" } + case 42 + ^ + : + return 42; + ~~~~~~ + { dg-end-multiline-output "" } */ + + default: + return val; + } +} diff --git a/gcc/testsuite/g++.dg/other/do1.C b/gcc/testsuite/g++.dg/other/do1.C index b3a9daf..db65e7d 100644 --- a/gcc/testsuite/g++.dg/other/do1.C +++ b/gcc/testsuite/g++.dg/other/do1.C @@ -7,7 +7,7 @@ void init () { - do { } while (0) - obj = 0; // { dg-error "expected|not declared" } + do { } while (0) // { dg-error "expected ';'" } + obj = 0; // { dg-error "not declared" } } diff --git a/gcc/testsuite/g++.dg/parse/error11.C b/gcc/testsuite/g++.dg/parse/error11.C index d118c19..1a49d6e 100644 --- a/gcc/testsuite/g++.dg/parse/error11.C +++ b/gcc/testsuite/g++.dg/parse/error11.C @@ -52,7 +52,7 @@ void func(void) Foo[:B> k1; // { dg-bogus "cannot begin|alternate spelling" "smart error should not be triggered here" } // { dg-error "6:missing template arguments before" "template" { target *-*-* } 51 } // { dg-error "9:expected primary-expression before ':' token" "primary" { target *-*-* } 51 } -// { dg-error "9:expected '\]' before ':' token" "backslash" { target *-*-* } 51 } +// { dg-error "8:expected '\]' before ':' token" "backslash" { target *-*-* } 51 } // { dg-error "6:missing template arguments before" "template" { target *-*-* } 52 } // { dg-error "7:expected primary-expression before ':' token" "primary" { target *-*-* } 52 } // { dg-error "7:expected '\]' before ':' token" "backslash" { target *-*-* } 52 } diff --git a/gcc/testsuite/g++.dg/parse/pragma2.C b/gcc/testsuite/g++.dg/parse/pragma2.C index c5616ff..eb0cf95 100644 --- a/gcc/testsuite/g++.dg/parse/pragma2.C +++ b/gcc/testsuite/g++.dg/parse/pragma2.C @@ -4,5 +4,5 @@ // does not. int f(int x, #pragma interface // { dg-error "not allowed here" } - // The parser gets confused and issues an error on the next line. - int y); // { dg-bogus "" "" { xfail *-*-* } } + // { dg-bogus "expected identifier" "" { xfail *-*-* } .-1 } + int y); diff --git a/gcc/testsuite/g++.dg/template/error11.C b/gcc/testsuite/g++.dg/template/error11.C index 3a469fd..1640298 100644 --- a/gcc/testsuite/g++.dg/template/error11.C +++ b/gcc/testsuite/g++.dg/template/error11.C @@ -1,4 +1,4 @@ // PR c++/12132 inline template void foo () {} // { dg-error "<" } -void abort (); // { dg-error ";" } +void abort (); // { dg-error ";" "" { target *-*-* } .-1 } diff --git a/gcc/testsuite/gcc.dg/missing-symbol-2.c b/gcc/testsuite/gcc.dg/missing-symbol-2.c new file mode 100644 index 0000000..7ee795d --- /dev/null +++ b/gcc/testsuite/gcc.dg/missing-symbol-2.c @@ -0,0 +1,71 @@ +/* { dg-options "-fdiagnostics-show-caret -Wno-switch-unreachable" } */ + +extern int foo (void); + +void missing_open_paren (void) +{ + if foo ()) /* { dg-line missing_open_paren } */ + { + } + /* { dg-error "expected '\\(' before 'foo'" "" { target c } missing_open_paren } */ + /* { dg-begin-multiline-output "" } + if foo ()) + ^~~ + ( + { dg-end-multiline-output "" } */ + /* { dg-error "expected statement before '\\)' token" "" { target c } missing_open_paren } */ + /* { dg-begin-multiline-output "" } + if foo ()) + ^ + { dg-end-multiline-output "" } */ +} + +void missing_close_square (void) +{ + const char test [42; /* { dg-error "22: expected ']' before ';' token" } */ + /* { dg-begin-multiline-output "" } + const char test [42; + ^ + ] + { dg-end-multiline-output "" } */ +} + +int missing_semicolon (void) +{ + return 42 /* { dg-error "expected ';'" } */ +} +/* { dg-begin-multiline-output "" } + return 42 + ^ + ; + } + ~ + { dg-end-multiline-output "" } */ + + +/* We don't offer a fix-it hint for this case in C, as it could be + colon or ellipsis. + TODO: we could be smarter about error-recovery here; given the + return perhaps we could assume a missing colon. */ + +int missing_colon_in_switch (int val) +{ + switch (val) + { + case 42 + return 42; /* { dg-error "expected ':' or '...' before 'return'" } */ + /* { dg-begin-multiline-output "" } + return 42; + ^~~~~~ + { dg-end-multiline-output "" } */ + + default: + return val; + } +} + +/* { dg-begin-multiline-output "" } + int dummy; + ^~~ + { dg-end-multiline-output "" } */ +int dummy;/* { dg-error "expected declaration or statement at end of input" "" { target c } } */ diff --git a/gcc/testsuite/gcc.dg/missing-symbol-3.c b/gcc/testsuite/gcc.dg/missing-symbol-3.c new file mode 100644 index 0000000..5449665 --- /dev/null +++ b/gcc/testsuite/gcc.dg/missing-symbol-3.c @@ -0,0 +1,50 @@ +/* { dg-options "-fdiagnostics-show-caret" } */ + +/* A sequence of bogus _Static_assert. + We can offer fix-it hints for some of these, but not all. */ + +void test_static_assert_1 (void) +{ + _Static_assert sizeof(int) >= sizeof(char); /* { dg-error "expected '\\(' before 'sizeof'" } */ + /* { dg-begin-multiline-output "" } + _Static_assert sizeof(int) >= sizeof(char); + ^~~~~~ + ( + { dg-end-multiline-output "" } */ +} + +void test_static_assert_2 (void) +{ + _Static_assert(sizeof(int) >= sizeof(char); /* { dg-error "expected ',' before ';' token" } */ + /* { dg-begin-multiline-output "" } + _Static_assert(sizeof(int) >= sizeof(char); + ^ + , + { dg-end-multiline-output "" } */ +} + +void test_static_assert_3 (void) +{ + _Static_assert(sizeof(int) >= sizeof(char),; /* { dg-error "expected string literal before ';' token" } */ + /* { dg-begin-multiline-output "" } + _Static_assert(sizeof(int) >= sizeof(char),; + ^ + { dg-end-multiline-output "" } */ +} + +void test_static_assert_4 (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 "" } */ +} + +/* The final one is correct. */ + +void test_static_assert_5 (void) +{ + _Static_assert(sizeof(int) >= sizeof(char), "msg"); +} diff --git a/gcc/testsuite/gcc.dg/noncompile/940112-1.c b/gcc/testsuite/gcc.dg/noncompile/940112-1.c index bb5e0f6..0a9e07d 100644 --- a/gcc/testsuite/gcc.dg/noncompile/940112-1.c +++ b/gcc/testsuite/gcc.dg/noncompile/940112-1.c @@ -3,5 +3,5 @@ f (int x) { double e = 1; e = 1; - return (e) -} /* { dg-error "parse error|syntax error|expected" } */ + return (e) /* { dg-error "parse error|syntax error|expected" } */ +} diff --git a/gcc/testsuite/gcc.dg/noncompile/971104-1.c b/gcc/testsuite/gcc.dg/noncompile/971104-1.c index 39e00c6..4a04dad 100644 --- a/gcc/testsuite/gcc.dg/noncompile/971104-1.c +++ b/gcc/testsuite/gcc.dg/noncompile/971104-1.c @@ -27,6 +27,6 @@ static void up(int sem){ printf("%s had processes sleeping on it!\n", ({ "MUTEX ", "BARB_SEM 1", "BARB_SEM 2", "CUST_SEM 1", "CUST_SEM 2", "WAIT_SEM 1", "WAIT_SEM 2", "WAIT_SEM 3", - "WAIT_SEM 4"} /* { dg-error "parse error|syntax error|expected" } */ - [( sb.sem_num )]) ); /* { dg-error "expected" } */ + "WAIT_SEM 4"} /* { dg-error "expected" } */ + [( sb.sem_num )]) ); } diff --git a/gcc/testsuite/obj-c++.dg/exceptions-6.mm b/gcc/testsuite/obj-c++.dg/exceptions-6.mm index 58882fe..6f6ba78 100644 --- a/gcc/testsuite/obj-c++.dg/exceptions-6.mm +++ b/gcc/testsuite/obj-c++.dg/exceptions-6.mm @@ -11,15 +11,15 @@ void test (id object) @throw object; /* Ok */ @throw; /* { dg-error ".@throw. .rethrow. used outside of a @catch block" } */ @throw (object); /* Ok. */ - @throw (id)0 -} /* { dg-error "expected" } */ + @throw (id)0 /* { dg-error "expected" } */ +} void test2 (id object) { @throw object); /* { dg-error "expected" } */ @throw (...); /* { dg-error "expected" } */ @throw (); /* { dg-error "expected" } */ - @throw + @throw /* { dg-error "expected" } */ } /* { dg-error "expected" } */ void test3 (id object1, id object2) diff --git a/gcc/testsuite/obj-c++.dg/pr48187.mm b/gcc/testsuite/obj-c++.dg/pr48187.mm index 750710b..99677a5 100644 --- a/gcc/testsuite/obj-c++.dg/pr48187.mm +++ b/gcc/testsuite/obj-c++.dg/pr48187.mm @@ -1,19 +1,19 @@ /* { dg-do compile } */ @interface A -{ +{ /* { dg-error "xpected" } */ ] /* { dg-error "xpected" } */ } @end @interface B -{ +{ /* { dg-error "xpected" } */ ]; /* { dg-error "xpected" } */ } @end @interface C -{ +{ /* { dg-error "xpected" } */ ]; /* { dg-error "xpected" } */ int x; } @@ -21,7 +21,7 @@ @interface D { - ( + ( /* { dg-error "xpected" } */ } /* { dg-error "xpected" } */ @end diff --git a/gcc/testsuite/objc.dg/exceptions-6.m b/gcc/testsuite/objc.dg/exceptions-6.m index 58882fe..74be98d 100644 --- a/gcc/testsuite/objc.dg/exceptions-6.m +++ b/gcc/testsuite/objc.dg/exceptions-6.m @@ -11,8 +11,8 @@ void test (id object) @throw object; /* Ok */ @throw; /* { dg-error ".@throw. .rethrow. used outside of a @catch block" } */ @throw (object); /* Ok. */ - @throw (id)0 -} /* { dg-error "expected" } */ + @throw (id)0 /* { dg-error "expected" } */ +} void test2 (id object) { -- 1.8.5.3