diff options
Diffstat (limited to 'clang/lib/Sema')
| -rw-r--r-- | clang/lib/Sema/SemaInit.cpp | 69 | 
1 files changed, 35 insertions, 34 deletions
| diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp index 9593489b806..7360eca1e99 100644 --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -2597,13 +2597,17 @@ static void TryReferenceInitialization(Sema &S,      return;    } -  //       - [If T1 is not a function type], if T2 is a class type and -  if (!T1Function && T2->isRecordType()) { -    bool isXValue = InitCategory.isXValue(); -    //       - the initializer expression is an rvalue and "cv1 T1" is  -    //         reference-compatible with "cv2 T2", or -    if (InitCategory.isRValue() &&  -        RefRelationship >= Sema::Ref_Compatible_With_Added_Qualification) { +  //    - If the initializer expression +  //      - is an xvalue, class prvalue, array prvalue, or function lvalue and +  //        "cv1 T1" is reference-compatible with "cv2 T2" +  // Note: functions are handled below. +  if (!T1Function && +      RefRelationship >= Sema::Ref_Compatible_With_Added_Qualification && +      (InitCategory.isXValue() || +       (InitCategory.isPRValue() && T2->isRecordType()) || +       (InitCategory.isPRValue() && T2->isArrayType()))) { +    ExprValueKind ValueKind = InitCategory.isXValue()? VK_XValue : VK_RValue; +    if (InitCategory.isPRValue() && T2->isRecordType()) {        // The corresponding bullet in C++03 [dcl.init.ref]p5 gives the        // compiler the freedom to perform a copy here or bind to the        // object, while C++0x requires that we bind directly to the @@ -2615,27 +2619,30 @@ static void TryReferenceInitialization(Sema &S,        //   be callable whether or not the copy is actually done.        if (!S.getLangOptions().CPlusPlus0x && !S.getLangOptions().Microsoft)          Sequence.AddExtraneousCopyToTemporary(cv2T2); - -      if (DerivedToBase) -        Sequence.AddDerivedToBaseCastStep( -                         S.Context.getQualifiedType(T1, T2Quals),  -                         isXValue ? VK_XValue : VK_RValue); -      else if (ObjCConversion) -        Sequence.AddObjCObjectConversionStep( -                                     S.Context.getQualifiedType(T1, T2Quals)); - -      if (T1Quals != T2Quals) -        Sequence.AddQualificationConversionStep(cv1T1, -                                            isXValue ? VK_XValue : VK_RValue); -      Sequence.AddReferenceBindingStep(cv1T1, /*bindingTemporary=*/!isXValue); -      return;      } - -    //       - T1 is not reference-related to T2 and the initializer expression -    //         can be implicitly converted to an rvalue of type "cv3 T3" (this -    //         conversion is selected by enumerating the applicable conversion -    //         functions (13.3.1.6) and choosing the best one through overload  -    //         resolution (13.3)), +         +    if (DerivedToBase) +      Sequence.AddDerivedToBaseCastStep(S.Context.getQualifiedType(T1, T2Quals), +                                        ValueKind); +    else if (ObjCConversion) +      Sequence.AddObjCObjectConversionStep( +                                       S.Context.getQualifiedType(T1, T2Quals)); +       +    if (T1Quals != T2Quals) +      Sequence.AddQualificationConversionStep(cv1T1, ValueKind); +    Sequence.AddReferenceBindingStep(cv1T1,  +         /*bindingTemporary=*/(InitCategory.isPRValue() && !T2->isArrayType())); +    return;       +  } +   +  //       - has a class type (i.e., T2 is a class type), where T1 is not  +  //         reference-related to T2, and can be implicitly converted to an  +  //         xvalue, class prvalue, or function lvalue of type "cv3 T3", +  //         where "cv1 T1" is reference-compatible with "cv3 T3", +  // +  // FIXME: Need to handle xvalue, class prvalue, etc. cases in  +  // TryRefInitWithConversionFunction. +  if (T2->isRecordType()) {      if (RefRelationship == Sema::Ref_Incompatible) {        ConvOvlResult = TryRefInitWithConversionFunction(S, Entity,                                                         Kind, Initializer, @@ -2652,13 +2659,7 @@ static void TryReferenceInitialization(Sema &S,      Sequence.SetFailed(InitializationSequence::FK_ReferenceInitDropsQualifiers);      return;    } -   -  //      - If the initializer expression is an rvalue, with T2 an array type, -  //        and "cv1 T1" is reference-compatible with "cv2 T2," the reference -  //        is bound to the object represented by the rvalue (see 3.10). -  // FIXME: How can an array type be reference-compatible with anything? -  // Don't we mean the element types of T1 and T2? -   +        //      - Otherwise, a temporary of type “cv1 T1” is created and initialized    //        from the initializer expression using the rules for a non-reference    //        copy initialization (8.5). The reference is then bound to the  | 

