re PR c++/55619 (Chromium build fails with: error: memory input is not directly addressable)
PR c++/55619 * c-parser.c (c_parser_asm_operands): Remove CONVERT_P argument, don't call default_function_array_conversion nor c_fully_fold here. (c_parser_asm_statement): Adjust callers. * c-typeck.c (build_asm_expr): Call c_fully_fold on inputs and outputs here, and call default_function_array_conversion on inputs that don't need to be addressable. * c-c++-common/pr55619.c: New test. From-SVN: r194631
This commit is contained in:
parent
1ac13b9c05
commit
eadd3d0d54
|
@ -1,3 +1,14 @@
|
|||
2012-12-20 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR c++/55619
|
||||
* c-parser.c (c_parser_asm_operands): Remove CONVERT_P
|
||||
argument, don't call default_function_array_conversion
|
||||
nor c_fully_fold here.
|
||||
(c_parser_asm_statement): Adjust callers.
|
||||
* c-typeck.c (build_asm_expr): Call c_fully_fold on inputs
|
||||
and outputs here, and call default_function_array_conversion
|
||||
on inputs that don't need to be addressable.
|
||||
|
||||
2012-12-18 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR c/39464
|
||||
|
|
|
@ -1154,7 +1154,7 @@ static void c_parser_while_statement (c_parser *);
|
|||
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, bool convert_p)
|
|||
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 %<)%>"))
|
||||
{
|
||||
|
|
|
@ -8502,6 +8502,8 @@ build_asm_expr (location_t loc, tree string, tree outputs, tree inputs,
|
|||
{
|
||||
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
|
||||
|
@ -8559,16 +8561,27 @@ build_asm_expr (location_t loc, tree string, tree outputs, tree inputs,
|
|||
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
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
2012-12-20 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR c++/55619
|
||||
* c-c++-common/pr55619.c: New test.
|
||||
|
||||
2012-12-20 Tobias Burnus <burnus@net-b.de>
|
||||
|
||||
PR fortran/54818
|
||||
|
|
|
@ -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));
|
||||
}
|
Loading…
Reference in New Issue