On Tue, Mar 20, 2018 at 5:04 PM, Jakub Jelinek <ja...@redhat.com> wrote: > Hi! > > While in C, x = 10 or ++x or --x aren't lvalues and so we reject such > expressions in inline asm output operands (and inputs that only allow > memory, not registers), in C++ they apparently are lvalues; for output > operands we ICE in the gimplifier on this, because in the generic code > MODIFY_EXPR or PREINCREMENT_EXPR or PREDECREMENT_EXPR aren't considered > to be lvalues, and for "m" inputs we just reject them, but when those > expressions are allowed on lhs of a store, they should be IMHO allowed > as "m" inputs too. > > Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux, ok for > trunk? > > 2018-03-20 Jakub Jelinek <ja...@redhat.com> > > PR c++/84961 > * semantics.c (finish_asm_stmt): Replace MODIFY_EXPR, > PREINCREMENT_EXPR > and PREDECREMENT_EXPR in output and "m" constrained input operands > with > COMPOUND_EXPR. Call cxx_mark_addressable on the rightmost > COMPOUND_EXPR operand. > > * c-c++-common/pr43690.c: Don't expect errors on "m" (--x) and > "m" (++x) in C++. > * g++.dg/torture/pr84961-1.C: New test. > * g++.dg/torture/pr84961-2.C: New test. > > --- gcc/cp/semantics.c.jj 2018-03-20 11:58:17.069356145 +0100 > +++ gcc/cp/semantics.c 2018-03-20 21:56:43.745292245 +0100 > @@ -1512,6 +1512,26 @@ finish_asm_stmt (int volatile_p, tree st > && C_TYPE_FIELDS_READONLY (TREE_TYPE (operand))))) > cxx_readonly_error (operand, lv_asm); > > + tree *op = &operand; > + while (TREE_CODE (*op) == COMPOUND_EXPR) > + op = &TREE_OPERAND (*op, 1); > + switch (TREE_CODE (*op)) > + { > + case PREINCREMENT_EXPR: > + case PREDECREMENT_EXPR: > + case MODIFY_EXPR: > + if (TREE_SIDE_EFFECTS (TREE_OPERAND (*op, 0))) > + *op = build2 (TREE_CODE (*op), TREE_TYPE (*op), > + cp_stabilize_reference (TREE_OPERAND (*op, 0)), > + TREE_OPERAND (*op, 1)); > + *op = build2 (COMPOUND_EXPR, TREE_TYPE (*op), *op, > + TREE_OPERAND (*op, 0)); > + op = &TREE_OPERAND (*op, 1); > + break; > + default: > + break; > + }
Hmm, it would be nice to share this with the similar patterns in unary_complex_lvalue and cp_build_modify_expr. Does COND_EXPR work without adjustment? Jason