aboutsummaryrefslogtreecommitdiff
path: root/gcc/c
diff options
context:
space:
mode:
authorSegher Boessenkool <segher@kernel.crashing.org>2019-01-02 23:49:04 +0100
committerSegher Boessenkool <segher@gcc.gnu.org>2019-01-02 23:49:04 +0100
commitba1cce8ea23459eef293f94acb43e43236f88249 (patch)
tree2dc56078fdac1815e737b229e07a56fbe4001e05 /gcc/c
parentf262721148a0b5a74096ad6711cd5f1820a333be (diff)
downloadgcc-ba1cce8ea23459eef293f94acb43e43236f88249.zip
gcc-ba1cce8ea23459eef293f94acb43e43236f88249.tar.gz
gcc-ba1cce8ea23459eef293f94acb43e43236f88249.tar.bz2
Backport of the "asm inline" patches
From-SVN: r267536
Diffstat (limited to 'gcc/c')
-rw-r--r--gcc/c/ChangeLog52
-rw-r--r--gcc/c/c-parser.c112
-rw-r--r--gcc/c/c-tree.h5
-rw-r--r--gcc/c/c-typeck.c11
4 files changed, 140 insertions, 40 deletions
diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog
index 2f27951..86a4c96 100644
--- a/gcc/c/ChangeLog
+++ b/gcc/c/ChangeLog
@@ -1,3 +1,55 @@
+2018-01-02 Segher Boessenkool <segher@kernel.crashing.org>
+
+ Backport from trunk
+ 2018-12-06 Segher Boessenkool <segher@kernel.crashing.org>
+
+ PR inline-asm/55681
+ * c-parser.c (c_parser_asm_statement): Update grammar. Allow any
+ combination of volatile and goto, in any order, without repetitions.
+
+ Backport from trunk
+ 2018-12-06 Segher Boessenkool <segher@kernel.crashing.org>
+
+ * c-parser.c (c_parser_asm_statement): Detect the inline keyword
+ after asm. Pass a flag for it to build_asm_expr.
+ * c-tree.h (build_asm_expr): Update declaration.
+ * c-typeck.c (build_asm_stmt): Add is_inline parameter. Use it to
+ set ASM_INLINE_P.
+
+ Backport from trunk
+ 2018-12-08 Segher Boessenkool <segher@kernel.crashing.org>
+
+ * c-parser (c_parser_asm_statement) [RID_INLINE]: Delete stray line
+ setting "quals".
+
+ Backport from trunk
+ 2018-12-19 Segher Boessenkool <segher@kernel.crashing.org>
+
+ * c-parser.c (c_parser_asm_statement): Rewrite the loop to work without
+ "done" boolean variable.
+
+ Backport from trunk
+ 2018-12-19 Segher Boessenkool <segher@kernel.crashing.org>
+
+ * 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.
+
+ Backport from trunk
+ 2018-12-19 Segher Boessenkool <segher@kernel.crashing.org>
+
+ * c-parser.c (c_parser_asm_statement) <RID_CONST, RID_RESTRICT>: Give
+ a more specific error message (instead of just falling through).
+
+ And extra for the backport
+ 2019-01-02 Segher Boessenkool <segher@kernel.crashing.org>
+
+ * c-parser.c (c_parser_asm_statement): Output a warning instead of an
+ error for const and restrict.
+
2018-12-06 Release Manager
* GCC 7.4.0 released.
diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c
index 101afb8..86195c5 100644
--- a/gcc/c/c-parser.c
+++ b/gcc/c/c-parser.c
@@ -6089,61 +6089,104 @@ c_parser_for_statement (c_parser *parser, bool ivdep, bool *if_p)
}
/* Parse an asm statement, a GNU extension. This is a full-blown asm
- statement with inputs, outputs, clobbers, and volatile tag
- allowed.
+ statement with inputs, outputs, clobbers, and volatile, inline, and goto
+ tags allowed.
+
+ asm-qualifier:
+ volatile
+ inline
+ goto
+
+ asm-qualifier-list:
+ asm-qualifier-list asm-qualifier
+ asm-qualifier
asm-statement:
- asm type-qualifier[opt] ( asm-argument ) ;
- asm type-qualifier[opt] goto ( asm-goto-argument ) ;
+ asm asm-qualifier-list[opt] ( asm-argument ) ;
asm-argument:
asm-string-literal
asm-string-literal : asm-operands[opt]
asm-string-literal : asm-operands[opt] : asm-operands[opt]
- asm-string-literal : asm-operands[opt] : asm-operands[opt] : asm-clobbers[opt]
-
- asm-goto-argument:
+ asm-string-literal : asm-operands[opt] : asm-operands[opt] \
+ : asm-clobbers[opt]
asm-string-literal : : asm-operands[opt] : asm-clobbers[opt] \
: asm-goto-operands
- Qualifiers other than volatile are accepted in the syntax but
- warned for. */
+ The form with asm-goto-operands is valid if and only if the
+ asm-qualifier-list contains goto, and is the only allowed form in that case.
+ Duplicate asm-qualifiers are not allowed. */
static tree
c_parser_asm_statement (c_parser *parser)
{
- tree quals, str, outputs, inputs, clobbers, labels, ret;
- bool simple, 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);
- if (c_parser_next_token_is_keyword (parser, RID_VOLATILE))
- {
- quals = c_parser_peek_token (parser)->value;
- c_parser_consume_token (parser);
- }
- else if (c_parser_next_token_is_keyword (parser, RID_CONST)
- || c_parser_next_token_is_keyword (parser, RID_RESTRICT))
- {
- warning_at (c_parser_peek_token (parser)->location,
- 0,
- "%E qualifier ignored on asm",
- c_parser_peek_token (parser)->value);
- quals = NULL_TREE;
- c_parser_consume_token (parser);
- }
- else
- quals = NULL_TREE;
- is_goto = false;
- if (c_parser_next_token_is_keyword (parser, RID_GOTO))
+ /* Handle the asm-qualifier-list. */
+ location_t volatile_loc = UNKNOWN_LOCATION;
+ location_t inline_loc = UNKNOWN_LOCATION;
+ location_t goto_loc = UNKNOWN_LOCATION;
+ for (;;)
{
- c_parser_consume_token (parser);
- is_goto = true;
+ c_token *token = c_parser_peek_token (parser);
+ location_t loc = token->location;
+ switch (token->keyword)
+ {
+ case RID_VOLATILE:
+ 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 (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 (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;
+
+ case RID_CONST:
+ case RID_RESTRICT:
+ warning_at (loc, 0, "%qE is not an asm qualifier", token->value);
+ c_parser_consume_token (parser);
+ continue;
+
+ default:
+ break;
+ }
+ 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;
@@ -6216,8 +6259,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));
+ 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;
diff --git a/gcc/c/c-tree.h b/gcc/c/c-tree.h
index 5fa32a4..eef26f8 100644
--- a/gcc/c/c-tree.h
+++ b/gcc/c/c-tree.h
@@ -659,8 +659,9 @@ extern tree build_compound_literal (location_t, tree, tree, bool);
extern void check_compound_literal_type (location_t, struct c_type_name *);
extern tree c_start_case (location_t, location_t, tree, bool);
extern void c_finish_case (tree, tree);
-extern tree build_asm_expr (location_t, tree, tree, tree, tree, tree, bool);
-extern tree build_asm_stmt (tree, tree);
+extern tree build_asm_expr (location_t, tree, tree, tree, tree, tree, bool,
+ bool);
+extern tree build_asm_stmt (bool, tree);
extern int c_types_compatible_p (tree, tree);
extern tree c_begin_compound_stmt (bool);
extern tree c_end_compound_stmt (location_t, tree, bool);
diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c
index 66a58a8..fd9fa2d 100644
--- a/gcc/c/c-typeck.c
+++ b/gcc/c/c-typeck.c
@@ -9669,9 +9669,9 @@ process_init_element (location_t loc, struct c_expr value, bool implicit,
(guaranteed to be 'volatile' or null) and ARGS (represented using
an ASM_EXPR node). */
tree
-build_asm_stmt (tree cv_qualifier, tree args)
+build_asm_stmt (bool is_volatile, tree args)
{
- if (!ASM_VOLATILE_P (args) && cv_qualifier)
+ if (is_volatile)
ASM_VOLATILE_P (args) = 1;
return add_stmt (args);
}
@@ -9680,10 +9680,12 @@ build_asm_stmt (tree cv_qualifier, tree args)
some INPUTS, and some CLOBBERS. The latter three may be NULL.
SIMPLE indicates whether there was anything at all after the
string in the asm expression -- asm("blah") and asm("blah" : )
- are subtly different. We use a ASM_EXPR node to represent this. */
+ are subtly different. We use a ASM_EXPR node to represent this.
+ LOC is the location of the asm, and IS_INLINE says whether this
+ is asm inline. */
tree
build_asm_expr (location_t loc, tree string, tree outputs, tree inputs,
- tree clobbers, tree labels, bool simple)
+ tree clobbers, tree labels, bool simple, bool is_inline)
{
tree tail;
tree args;
@@ -9801,6 +9803,7 @@ build_asm_expr (location_t loc, tree string, tree outputs, tree inputs,
as volatile. */
ASM_INPUT_P (args) = simple;
ASM_VOLATILE_P (args) = (noutputs == 0);
+ ASM_INLINE_P (args) = is_inline;
return args;
}