On Mar  7, 2005, Roger Sayle <[EMAIL PROTECTED]> wrote:

> For example, I believe that Alex's proposed solution to PR c++/19199
> isn't an appropriate fix.  It's perfectly reasonable for fold to convert
> a C++ COND_EXPR into a MIN_EXPR or MAX_EXPR, as according to the C++
> front-end all three of these tree nodes are valid lvalues.

But not if the values it places in the MIN_EXPR or MAX_EXPR operands
aren't lvalues themselves, otherwise you're turning an lvalue into an
rvalue.  In the example of this testcase, the compare operands are
<nop(int) <parm_decl>> (rvalues), whereas the cond_expr operands are
<parm_decl> (lvalues), and the min_expr operands end up being
<nop(int) <parm_decl>>.  So the transformation is in error.

It wouldn't be if we managed to first remove the extensions from the
compare operands, and only then turn them into min/max_expr.  Any
reason to avoid comparing the enums directly, without wrapping them in
conversions to int?

> It also doesn't help with the problematic C++ extension:

>       (a >? b) = c;

> which use MIN_EXPR/MAX_EXPR as a valid lvalue in C++ without any help
> from "fold".

As long as there isn't any conversion needed for the compare.

> The first is to see if in the C++ parser provides enough information
> such that it knows we're if parsing an lvalue or an rvalue.

It doesn't, and it can't.  Consider:

( void ) ( ( a ? b : c )  )
( void ) ( ( a ? b : c ) = 0)
                      ^ you're here

how could you possibly tell one from the other without looking too far
ahead?

> In these cases, the C++ front-end can avoid calling "fold" on the
> COND_EXPR its creating in build_conditional_expr.  This only impacts
> that C++ front-end and doesn't impact performance of C/fortran/java
> code that may usefully take advantage of min/max.

See that I've already suggested the solution for the other languages
in which cond_expr is never an lvalue: make sure they turn the
operands of the cond_expr into non-lvalues, even if this demands
gratuitous non_lvalue_exprs or nops.

> An improvement on this approach is for the C++ front-end never to create
> COND_EXPR, MIN_EXPR or MAX_EXPR as the target of MODIFY_EXPRs, and lower
> them itself upon creation.  By forbidding them in "generic", support for
> COND_EXPRs as lvalues can be removed from language-independent
> gimplification, fold, non_lvalue, etc... greatly simplifying the compiler.

This isn't a complete solution.  MODIFY_EXPR is not the only situation
in which lvalueness of a COND_EXPR is relevant.  You may have to bind
a reference to the result of a COND_EXPR.

> Finally, the third approach would be to introduce new tree codes for
> LCOND_EXPR, LMIN_EXPR and LMAX_EXPR that reflect the subtley different
> semantics of these operators when uses as lvalues.

Why bother?  We already handle them all properly, except for this one
case that mis-handles COND_EXPRs whose compares include extensions.
We can fix that, and not lose performance by getting front-ends that
can offer guarantees about non-lvalueness of COND_EXPRs to give this
information to the middle end.

> My final comment is that in the lowering of (a ? b : c) = d by using
> a pointer temporary runs into the problems with bitfields "b" and "c",
> and marking of objects addressable when they need not be.

Yup.

> runs into problems.  A better approach it to use a temporary for "d".

Yup, we have a transformation that does just that at some point.  But
again, it only operates on MODIFY_EXPRs, it can't help for the other
important lvalue case, that of reference-binding.


Hmm...  Maybe we could generate the COND_EXPR without folding, and
then, when we use it as an rvalue, we fold it; when it use it as an
lvalue, we transform it in something else that is fold-resistant.  I'm
not sure I like this, but I suppose it's the only way to go if we
don't want to enable COND_EXPR, MIN_EXPR and MAX_EXPR to be handled as
lvalues in the middle end.

-- 
Alexandre Oliva             http://www.ic.unicamp.br/~oliva/
Red Hat Compiler Engineer   [EMAIL PROTECTED], gcc.gnu.org}
Free Software Evangelist  [EMAIL PROTECTED], gnu.org}

Reply via email to