https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114388
--- Comment #7 from Jiang An <de34 at live dot cn> --- (In reply to Jonathan Wakely from comment #5) > Prior to DR 616 the expression (true ? WrapB().b : WrapD().d) was a prvalue > of type B, created by copying the B (or slicing the D when the condition is > false). As an rvalue, it wasn't evaluated. That's true pre-N3055 and > post-N3055. > > DR 616 changed WrapB().b to be an xvalue, and the result of the expression > is B&& in C++1 (and const B& in C++98 I guess). > > In C++98 the const B& is an lvalue, and in C++11 the B&& is an xvalue which > is a glvalue. Either way, it's correct to treat it as a glvalue of > polymorphic type and evaluate it. > > So this change is not caused by N3055. And I think G++ is correct for both > C++98 and C++11. So INVALID. Pre-N3055 there were no xvalue branch in [expr.cond], and (later-called) xvalues were handled alongwith prvalues. I don't see anything in C++98 [expr.cond] adding const& when there's no const values. This example also shows that GCC hasn't been thinking that the result of the expression is const B& in C++98: https://godbolt.org/z/EPv65oY1W.