Hi!

As the testcase shows, for "m" or similar constraints that don't accept
registers, but do accept memory, we want to call *mark_addressable on the
operand, but the call to decay_conversion can change something that was
originally addressable into something non-addressable (be it replacement
of a const var with its initializer, or e.g. when the argument is an array).

The following patch fixes that, bootstrapped/regtested on x86_64-linux and
i686-linux, ok for trunk?  The C FE might need some change too (const vars
aren't an issue, but array conversions are).

2012-12-11  Jakub Jelinek  <ja...@redhat.com>

        PR c++/55619
        * semantics.c (finish_asm_stmt): Don't call decay_conversion
        on input operands that can be only in memory.

        * g++.dg/ext/asm12.C: New test.

--- gcc/cp/semantics.c.jj       2012-12-10 08:42:39.000000000 +0100
+++ gcc/cp/semantics.c  2012-12-10 15:24:20.666231490 +0100
@@ -1369,7 +1369,15 @@ finish_asm_stmt (int volatile_p, tree st
       for (i = 0, t = input_operands; t; ++i, t = TREE_CHAIN (t))
        {
          constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (t)));
-         operand = decay_conversion (TREE_VALUE (t), tf_warning_or_error);
+         bool constraint_parsed
+           = parse_input_constraint (&constraint, i, ninputs, noutputs, 0,   
+                                     oconstraints, &allows_mem, &allows_reg);
+         /* If the operand is going to end up in memory, don't call
+            decay_conversion.  */
+         if (constraint_parsed && !allows_reg && allows_mem)
+           operand = mark_rvalue_use (TREE_VALUE (t));
+         else
+           operand = decay_conversion (TREE_VALUE (t), tf_warning_or_error);
 
          /* If the type of the operand hasn't been determined (e.g.,
             because it involves an overloaded function), then issue
@@ -1382,8 +1390,7 @@ finish_asm_stmt (int volatile_p, tree st
              operand = error_mark_node;
            }
 
-         if (parse_input_constraint (&constraint, i, ninputs, noutputs, 0,
-                                     oconstraints, &allows_mem, &allows_reg))
+         if (constraint_parsed)
            {
              /* If the operand is going to end up in memory,
                 mark it addressable.  */
--- gcc/testsuite/g++.dg/ext/asm12.C.jj 2012-12-10 15:28:26.313827902 +0100
+++ gcc/testsuite/g++.dg/ext/asm12.C    2012-12-10 15:28:03.000000000 +0100
@@ -0,0 +1,14 @@
+// PR c++/55619
+// { dg-do compile }
+
+typedef int V __attribute__ ((vector_size (4 * sizeof (int))));
+
+static const V C = { 0x201, 0, 0, 0 };
+static const int D = 0x201;
+
+void
+f ()
+{
+  __asm volatile ("" : : "m" (C));
+  __asm volatile ("" : : "m" (D));
+}

        Jakub

Reply via email to