This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[C PATCH] Don't perform function array conversions on inline asm "m" constrainted inputs (PR c++/55619)
- From: Jakub Jelinek <jakub at redhat dot com>
- To: "Joseph S. Myers" <joseph at codesourcery dot com>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Wed, 12 Dec 2012 20:54:53 +0100
- Subject: [C PATCH] Don't perform function array conversions on inline asm "m" constrainted inputs (PR c++/55619)
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
Hi!
This is something I've changed recently on the C++ side, but C has similar
issue as the testcase shows. For "m" or other constraints that allow memory
and don't allow registers, we want to mark the operand addressable (thus
handle it quite lvalue-ish, except that we know it won't be written to),
but default_function_array_conversion can be a problem for that.
Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux, ok for
trunk?
2012-12-12 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.
* c-c++-common/pr55619.c: New test.
--- gcc/c/c-parser.c.jj 2012-11-19 14:41:12.000000000 +0100
+++ gcc/c/c-parser.c 2012-12-12 14:02:37.062065983 +0100
@@ -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 %<)%>"))
{
--- gcc/c/c-typeck.c.jj 2012-12-10 08:42:35.000000000 +0100
+++ gcc/c/c-typeck.c 2012-12-12 14:11:55.487236911 +0100
@@ -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
--- gcc/testsuite/c-c++-common/pr55619.c.jj 2012-12-12 14:25:24.514694819 +0100
+++ gcc/testsuite/c-c++-common/pr55619.c 2012-12-12 14:25:55.183538437 +0100
@@ -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));
+}
Jakub