@@ -1154,7 +1154,7 @@ static void c_parser_while_statement (c_
static void c_parser_do_statement (c_parser *);
static void c_parser_for_statement (c_parser *);
static tree c_parser_asm_statement (c_parser *);
-static tree c_parser_asm_operands (c_parser *, bool);
+static tree c_parser_asm_operands (c_parser *);
static tree c_parser_asm_goto_operands (c_parser *);
static tree c_parser_asm_clobbers (c_parser *);
static struct c_expr c_parser_expr_no_commas (c_parser *, struct c_expr *);
@@ -5150,10 +5150,10 @@ c_parser_asm_statement (c_parser *parser
/* For asm goto, we don't allow output operands, but reserve
the slot for a future extension that does allow them. */
if (!is_goto)
- outputs = c_parser_asm_operands (parser, false);
+ outputs = c_parser_asm_operands (parser);
break;
case 1:
- inputs = c_parser_asm_operands (parser, true);
+ inputs = c_parser_asm_operands (parser);
break;
case 2:
clobbers = c_parser_asm_clobbers (parser);
@@ -5191,9 +5191,7 @@ c_parser_asm_statement (c_parser *parser
goto error;
}
-/* Parse asm operands, a GNU extension. If CONVERT_P (for inputs but
- not outputs), apply the default conversion of functions and arrays
- to pointers.
+/* Parse asm operands, a GNU extension.
asm-operands:
asm-operand
@@ -5205,10 +5203,9 @@ c_parser_asm_statement (c_parser *parser
*/
static tree
-c_parser_asm_operands (c_parser *parser, bool convert_p)
+c_parser_asm_operands (c_parser *parser)
{
tree list = NULL_TREE;
- location_t loc;
while (true)
{
tree name, str;
@@ -5243,12 +5240,8 @@ c_parser_asm_operands (c_parser *parser,
parser->lex_untranslated_string = true;
return NULL_TREE;
}
- loc = c_parser_peek_token (parser)->location;
expr = c_parser_expression (parser);
mark_exp_read (expr.value);
- if (convert_p)
- expr = default_function_array_conversion (loc, expr);
- expr.value = c_fully_fold (expr.value, false, NULL);
parser->lex_untranslated_string = true;
if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
{
@@ -8500,6 +8500,8 @@ build_asm_expr (location_t loc, tree str
{
tree output = TREE_VALUE (tail);
+ output = c_fully_fold (output, false, NULL);
+
/* ??? Really, this should not be here. Users should be using a
proper lvalue, dammit. But there's a long history of using casts
in the output operands. In cases like longlong.h, this becomes a
@@ -8557,16 +8559,27 @@ build_asm_expr (location_t loc, tree str
mark it addressable. */
if (!allows_reg && allows_mem)
{
+ input = c_fully_fold (input, false, NULL);
+
/* Strip the nops as we allow this case. FIXME, this really
should be rejected or made deprecated. */
STRIP_NOPS (input);
if (!c_mark_addressable (input))
input = error_mark_node;
}
- else if (input != error_mark_node && VOID_TYPE_P (TREE_TYPE (input)))
+ else
{
- error_at (loc, "invalid use of void expression");
- input = error_mark_node;
+ struct c_expr expr;
+ memset (&expr, 0, sizeof (expr));
+ expr.value = input;
+ expr = default_function_array_conversion (loc, expr);
+ input = c_fully_fold (expr.value, false, NULL);
+
+ if (input != error_mark_node && VOID_TYPE_P (TREE_TYPE (input)))
+ {
+ error_at (loc, "invalid use of void expression");
+ input = error_mark_node;
+ }
}
}
else
@@ -0,0 +1,11 @@
+/* PR c++/55619 */
+/* { dg-do compile } */
+
+int y[4];
+
+void
+f ()
+{
+ int x[4] = { 0, 1, 2, 3 };
+ __asm volatile ("" : : "m" (x), "m" (y));
+}