aboutsummaryrefslogtreecommitdiff
path: root/gcc/c/c-parser.c
diff options
context:
space:
mode:
authorSegher Boessenkool <segher@kernel.crashing.org>2018-12-19 17:12:17 +0100
committerSegher Boessenkool <segher@gcc.gnu.org>2018-12-19 17:12:17 +0100
commitdb4fd626ee2bb431adadddf5eca5fba104cea5ca (patch)
tree1a0695e86a028584e80b85b341d91e2c3755519c /gcc/c/c-parser.c
parent9c9cfcbbbe659d16a216883ff9a9bcb098e243f0 (diff)
downloadgcc-db4fd626ee2bb431adadddf5eca5fba104cea5ca.zip
gcc-db4fd626ee2bb431adadddf5eca5fba104cea5ca.tar.gz
gcc-db4fd626ee2bb431adadddf5eca5fba104cea5ca.tar.bz2
c/c++, asm: Use nicer error for duplicate asm qualifiers
Also as suggested by Jason. c/ * c-parser.c (c_parser_asm_statement): Keep track of the location each asm qualifier is first seen; use that to give nicer "duplicate asm qualifier" messages. Delete 'quals" variable, instead pass the "is_volatile_ flag to build_asm_stmt directly. * c-tree.h (build_asm_stmt): Make the first arg bool instead of tree. * c-typeck.c (build_asm_stmt): Ditto; adjust. cp/ * parser.c (cp_parser_asm_definition): Rewrite the loop to work without "done" boolean variable. * parser.c (cp_parser_asm_definition): Keep track of the location each asm qualifier is first seen; use that to give nicer "duplicate asm qualifier" messages. From-SVN: r267278
Diffstat (limited to 'gcc/c/c-parser.c')
-rw-r--r--gcc/c/c-parser.c57
1 files changed, 37 insertions, 20 deletions
diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c
index 835c0d8..652e53c 100644
--- a/gcc/c/c-parser.c
+++ b/gcc/c/c-parser.c
@@ -6360,41 +6360,54 @@ c_parser_for_statement (c_parser *parser, bool ivdep, unsigned short unroll,
static tree
c_parser_asm_statement (c_parser *parser)
{
- tree quals, str, outputs, inputs, clobbers, labels, ret;
- bool simple, is_volatile, is_inline, is_goto;
+ tree str, outputs, inputs, clobbers, labels, ret;
+ bool simple;
location_t asm_loc = c_parser_peek_token (parser)->location;
int section, nsections;
gcc_assert (c_parser_next_token_is_keyword (parser, RID_ASM));
c_parser_consume_token (parser);
- quals = NULL_TREE;
- is_volatile = false;
- is_inline = false;
- is_goto = false;
+ /* Handle the asm-qualifier-list. */
+ location_t volatile_loc = UNKNOWN_LOCATION;
+ location_t inline_loc = UNKNOWN_LOCATION;
+ location_t goto_loc = UNKNOWN_LOCATION;
for (;;)
{
- switch (c_parser_peek_token (parser)->keyword)
+ c_token *token = c_parser_peek_token (parser);
+ location_t loc = token->location;
+ switch (token->keyword)
{
case RID_VOLATILE:
- if (is_volatile)
- break;
- is_volatile = true;
- quals = c_parser_peek_token (parser)->value;
+ if (volatile_loc)
+ {
+ error_at (loc, "duplicate asm qualifier %qE", token->value);
+ inform (volatile_loc, "first seen here");
+ }
+ else
+ volatile_loc = loc;
c_parser_consume_token (parser);
continue;
case RID_INLINE:
- if (is_inline)
- break;
- is_inline = true;
+ if (inline_loc)
+ {
+ error_at (loc, "duplicate asm qualifier %qE", token->value);
+ inform (inline_loc, "first seen here");
+ }
+ else
+ inline_loc = loc;
c_parser_consume_token (parser);
continue;
case RID_GOTO:
- if (is_goto)
- break;
- is_goto = true;
+ if (goto_loc)
+ {
+ error_at (loc, "duplicate asm qualifier %qE", token->value);
+ inform (goto_loc, "first seen here");
+ }
+ else
+ goto_loc = loc;
c_parser_consume_token (parser);
continue;
@@ -6404,6 +6417,10 @@ c_parser_asm_statement (c_parser *parser)
break;
}
+ bool is_volatile = (volatile_loc != UNKNOWN_LOCATION);
+ bool is_inline = (inline_loc != UNKNOWN_LOCATION);
+ bool is_goto = (goto_loc != UNKNOWN_LOCATION);
+
/* ??? Follow the C++ parser rather than using the
lex_untranslated_string kludge. */
parser->lex_untranslated_string = true;
@@ -6478,9 +6495,9 @@ c_parser_asm_statement (c_parser *parser)
if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
c_parser_skip_to_end_of_block_or_statement (parser);
- ret = build_asm_stmt (quals, build_asm_expr (asm_loc, str, outputs, inputs,
- clobbers, labels, simple,
- is_inline));
+ ret = build_asm_stmt (is_volatile,
+ build_asm_expr (asm_loc, str, outputs, inputs,
+ clobbers, labels, simple, is_inline));
error:
parser->lex_untranslated_string = false;