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