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: [PR c++/20280] hoist indirect_ref out of addressable cond_exprs


Alexandre Oliva wrote:


+  // Hmm...  I don't think these should be accepted.  The conditional
+  // expressions are lvalues for sure, and 8.5.3/5 exempts lvalues
+  // that are bit-fields, but not lvalues that are conditional
+  // expressions involving bit-fields.
+  h (b ? x.i : x.j);
+  h (b ? x.i : x.k);
+  h (b ? x.j : x.k);


That's legal because "h" takes a "const &", which permits the compiler
to create a temporary.


Yeah, it permits, but only in certain circumstances that AFAICT aren't
met.  This expression AFAICT is an lvalue that isn't a bit-field, so
it has to bind directly, per the first bullet in 8.5.3/5.  Since it
meets the conditions of this first bullet, it doesn't get to use the
`otherwise' portion of that paragraph, that creates a temporary.  Or
am I misreading anything?

The situation is a little unclear.


EDG also accepts this code, which is part of what confused me.

Your reading is logical, but it depends on exactly what "lvalue for a bit-field" means. (Note that it does not say "lvalue *is* a bit-field"; it says "lvalue *for* a bit-field".)

Consider:

h((0, x.i));

It would be odd not to allow that, but to allow "h(x.i)". The comma-expression isn't changing what's being passed to "h". The same goes for "h((x.i = 3))".

I think that, if anything, there's a possible defect in the standard here, not a defect in the compiler.

And, I think these kinds of transformations (if necessary) should be
done in a langhook during gimplification, not at COND_EXPR-creation
time.  We really want the C++ front-end's data structures to be an
accurate mirror of the input program for as long as possible.
Err... But in what sense does my patch change that? See, what I'm
doing is hoisting the indirect_refs that are inserted by
stabilize_reference out of the cond_expr. They weren't in the
original code. There's no dereferencing going on unless the whole
expression undergoes lvalue-to-rvalue decay, so I'd argue that the
transformation I'm proposing actually matches even more accurately the
meaning of the original source code.

Actually, looking at this more closely, I think that something is forgetting to call rationalize_conditional_expr, which is normally called from unary_complex_lvalue. When the conditional expression is used in the lvalue context, something should be calling that. Normally, that happens because something calls build_unary_op (ADDR_EXPR, ...) on the COND_EXPR.


It may be that I changed something to call build_addr (instead of build_unary_op) in a case where that's not safe. Can you confirm or deny that hypothesis?

Thanks,

--
Mark Mitchell
CodeSourcery, LLC
mark@codesourcery.com
(916) 791-8304


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