Fixed in r161450.<br><br><div class="gmail_quote">On Mon, Aug 6, 2012 at 10:59 PM, Eli Friedman <span dir="ltr"><<a href="mailto:eli.friedman@gmail.com" target="_blank">eli.friedman@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div class="HOEnZb"><div class="h5">On Mon, Aug 6, 2012 at 10:44 PM, Richard Smith <<a href="mailto:richard@metafoo.co.uk">richard@metafoo.co.uk</a>> wrote:<br>
> Hi David,<br>
><br>
>> On Mon, Aug 6, 2012 at 6:54 PM, David Wood <<a href="mailto:dswood@gmail.com">dswood@gmail.com</a>> wrote:<br>
>> > The following compiles fine in macports gcc 4.7, but does not in clang<br>
>> > svn<br>
>> > 161307.  I believe the key is the const reference in combination with<br>
>> > the ?:<br>
>> > operator.<br>
>> ><br>
>> > #include <stdexcept><br>
>> ><br>
>> > struct A {<br>
>> >   constexpr A(int a) : value(a) {}<br>
>> ><br>
>> >   constexpr int get() { return value; }<br>
>> ><br>
>> > private:<br>
>> >   int value;<br>
>> > };<br>
>> ><br>
>> > constexpr A someFn(const A& a) {<br>
>> >   return a.get() == 0 ? throw std::exception() : a;<br>
>> > }<br>
>> ><br>
>> > int main(int argc, char** argv) {<br>
>> >   constexpr A a(4);<br>
>> >   static_assert( someFn(a).get() == 4, "error" );<br>
>> > }<br>
>> ><br>
>> > Some digging on the internets reveals<br>
>> ><br>
>> > <a href="http://stackoverflow.com/questions/5605142/stdmax-and-stdmin-not-constexpr" target="_blank">http://stackoverflow.com/questions/5605142/stdmax-and-stdmin-not-constexpr</a>,<br>
>> > which seems to point to lvalues, glvalues and memory allocation,<br>
>> > although I<br>
>> > did not follow it very well.  There is also the particularly interesting<br>
>> > comment :<br>
>> ><br>
>> > The C++ committee have suggested that it was intended to be possible for<br>
>> > function invocation substitution to produce an lvalue referring to a<br>
>> > temporary. g++ behaves that way, but clang currently implements the<br>
>> > standard<br>
>> > as written.<br>
><br>
><br>
> That comment is out of date. At the most recent C++ standards committee<br>
> meeting, we decided to allow such cases, and Clang now supports them.<br>
><br>
>><br>
>> > So, I have two questions.  1) Is the way clang handles this in fact<br>
>> > conformant to the spec, and gcc is lax?<br>
><br>
><br>
> This code is well-formed, we're incorrect to reject it. Please file a bug at<br>
> <a href="http://llvm.org/bugs" target="_blank">llvm.org/bugs</a>.<br>
><br>
> We are rejecting it because we have produced a broken AST:<br>
><br>
> (CompoundStmt 0x4024650 <<stdin>:10:32, line:12:1><br>
>   (ReturnStmt 0x4024630 <line:11:3, col:35><br>
>     (CXXConstructExpr 0x40245f8 <col:10, col:35> 'struct A''void (const<br>
> struct A &) noexcept' elidable<br>
>       (MaterializeTemporaryExpr 0x40244d0 <col:10, col:35> 'const struct A'<br>
> lvalue<br>
>         (ConditionalOperator 0x4024128 <col:10, col:35> 'const struct A'<br>
>           (BinaryOperator 0x4024098 <col:10, col:21> '_Bool' '=='<br>
>             (CXXMemberCallExpr 0x4024050 <col:10, col:16> 'int'<br>
>               (MemberExpr 0x4024020 <col:10, col:12> '<bound member function<br>
> type>' .get 0x4023af0<br>
>                 (DeclRefExpr 0x4023ff8 <col:10> 'const struct A' lvalue<br>
> ParmVar 0x4023e90 'a' 'const struct A &')))<br>
>             (IntegerLiteral 0x4024078 <col:21> 'int' 0))<br>
>           (CXXThrowExpr 0x40240e0 <col:25, col:31> 'void'<br>
>             (IntegerLiteral 0x40240c0 <col:31> 'int' 0))<br>
>           (DeclRefExpr 0x4024100 <col:35> 'const struct A' lvalue ParmVar<br>
> 0x4023e90 'a' 'const struct A &'))))))<br>
><br>
> Note that the ConditionalOperator is an rvalue, but its third operand is an<br>
> lvalue, with no intervening CXXConstructExpr. That's wrong -- we're supposed<br>
> to perform an lvalue-to-rvalue conversion on this operand (see<br>
> [expr.cond]p2).<br>
<br>
</div></div>Err, oops, you're right; I somehow misread the testcase.<br>
<span class="HOEnZb"><font color="#888888"><br>
-Eli<br>
</font></span></blockquote></div><br>