[Bug c++/20280] [4.0/4.1 regression] ICE in create_tmp_var, at gimplify.c:368
mark at codesourcery dot com
gcc-bugzilla@gcc.gnu.org
Fri Mar 4 07:27:00 GMT 2005
------- 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
More information about the Gcc-bugs
mailing list