[cfe-commits] r138715 - in /cfe/trunk: lib/Sema/SemaExpr.cpp test/CXX/special/class.temporary/p1.cpp

Johannes Schaub schaub.johannes at googlemail.com
Sun Aug 28 02:34:28 PDT 2011

John McCall wrote:

> On Aug 27, 2011, at 4:15 PM, Johannes Schaub wrote:
>> John McCall wrote:
>>> Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
>>> URL:
>>> http://llvm.org/viewvc/llvm-
>>> --- cfe/trunk/lib/Sema/SemaExpr.cpp (original) +++
>>> cfe/trunk/lib/Sema/SemaExpr.cpp Sat Aug 27 17:06:17 2011 @@ -443,9
>>> +443,15 @@
>>>   if (Ty->isSpecificBuiltinType(BuiltinType::Float))
>>>     E = ImpCastExprToType(E, Context.DoubleTy, CK_FloatingCast).take();
>>> -  // C++ includes lvalue-to-rvalue conversion as a default argument
>>> -  // promotion.  If we have a gl-value, initialize a temporary.
>>> -  if (getLangOptions().CPlusPlus && E->isGLValue()) {
>>> +  // C++ performs lvalue-to-rvalue conversion as a default argument
>>> +  // promotion.  If we still have a gl-value after usual unary
>>> +  // conversion, we must have an l-value of class type, so we need to
>>> +  // initialize a temporary.  For compatibility reasons, however, we
>>> +  // don't want to do this in unevaluated contexts; otherwise we
>>> +  // reject metaprograms which work by passing uncopyable l-values to
>>> +  // variadic functions.
>> 4.1p2 of the C++11 FDIS says:
>> "When an lvalue-to-rvalue conversion occurs in an unevaluated operand or
>> a subexpression thereof (Clause 5) the value contained in the referenced
>> object is not accessed. Otherwise ...".
>> C++03 is much less precise on the entire conversion wrt class types, but
>> said if the expression occurs within the operand of a sizeof "the value
>> contained in the referenced object is not accessed". I think the FDIS
>> text will be a good reference to put on that comment.
> I'm not sure how this applies.  I agree that the lvalue-to-rvalue
> conversion, if well-formed, does not access the object if it appears in an
> unevaluated
> context.  However, the conversion is not necessarily well-formed, and
> normally that's checked even in unevaluated contexts.

Not only is the value not accessed at runtime, but there is also no copy 
initialization done at all. That's what is explicit in the C++0x FDIS. 
That's the purpose of "Otherwise [if we are in an evaluated context], ...".

There is no such rule that says similar things for access checking when 
calling a member function. So you of course still have to check access when 
calling a member function. 

That's much the same treatment as what has been done to creation of a 
temporary as the result of analyzing the toplevel expression of a decltype:

    struct A { private: ~A(); };
    A f();
    int main() { 
      // well-formed
      // ill-formed

Just like for the lvalue to rvalue conversion, in that case we too have an 
explicit rule that in that particular case, no temporary is created and to 
be destroyed. 

More information about the cfe-commits mailing list