------- Additional Comments From mark at codesourcery dot com 2005-03-04 07:26 ------- Subject: 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, -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20280