re PR c++/55619 (Chromium build fails with: error: memory input is not directly addre...
authorJakub Jelinek <jakub@redhat.com>
Thu, 20 Dec 2012 10:41:47 +0000 (11:41 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Thu, 20 Dec 2012 10:41:47 +0000 (11:41 +0100)
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

gcc/c/ChangeLog
gcc/c/c-parser.c
gcc/c/c-typeck.c
gcc/testsuite/ChangeLog
gcc/testsuite/c-c++-common/pr55619.c [new file with mode: 0644]

index f2ee562cf4bab568553bcbf0d4ebdd2fe94985c8..8c90c5568ce454a3852050e999249ab71e2c6d9e 100644 (file)
@@ -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
index d85bff0a2d982081773fa27ae194e7219c6aef9d..ef5973fbb7df8a55eaace692595123cb2a0ec09f 100644 (file)
@@ -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 %<)%>"))
        {
index 6dddf7abd9957a2e488a909af253a9a6ccd86cab..5f2df6797ad57ed2452782c9f72055d4eb3b582c 100644 (file)
@@ -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
index 5ff977cb1c05dd24a70607729c1be80df895ab93..1b7c851df3838ce1741a44975ad5f39f385714af 100644 (file)
@@ -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
diff --git a/gcc/testsuite/c-c++-common/pr55619.c b/gcc/testsuite/c-c++-common/pr55619.c
new file mode 100644 (file)
index 0000000..f1b4e9c
--- /dev/null
@@ -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));
+}