This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: C++ PATCH for c++/70744 (wrong-code with x ?: y extension)


On 04/22/2016 07:50 AM, Marek Polacek wrote:
This PR shows that we generate wrong code with the x ?: y extension in case the
first operand contains either predecrement or preincrement.  The problem is
that we don't emit SAVE_EXPR, thus the operand is evaluated twice, which it
should not be.

While ++i or --i can be lvalues in C++, i++ or i-- can not.  The code in
build_conditional_expr_1 has:
  4635       /* Make sure that lvalues remain lvalues.  See g++.oliva/ext1.C.  */
  4636       if (real_lvalue_p (arg1))
  4637         arg2 = arg1 = stabilize_reference (arg1);
  4638       else
  4639         arg2 = arg1 = save_expr (arg1);
so for ++i/--i we call stabilize_reference, but that doesn't know anything
about PREINCREMENT_EXPR or PREDECREMENT_EXPR and just returns the same
expression, so SAVE_EXPR isn't created.

I think one fix would be to teach stabilize_reference what to do with those,
similarly to how we handle COMPOUND_EXPR there.

Your change will turn the expression into an rvalue, so that isn't enough. We need to turn the expression into some sort of _REF before passing it to stabilize_reference, perhaps by factoring out the cast-to-reference code from force_paren_expr. This should probably be part of a cp_stabilize_reference function that replaces all uses of stabilize_reference in the front end.

Jason


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]