]> granicus.if.org Git - clang/commitdiff
Kill off two more uses of Sema::CheckReferenceInit in favor of the new
authorDouglas Gregor <dgregor@apple.com>
Thu, 25 Mar 2010 00:20:38 +0000 (00:20 +0000)
committerDouglas Gregor <dgregor@apple.com>
Thu, 25 Mar 2010 00:20:38 +0000 (00:20 +0000)
initialization code. Exposed a bug where we were not marking an
implicit conversion as an lvalue when we were forming a call to a
conversion function whose return type is a reference.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@99459 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaCXXCast.cpp
lib/Sema/SemaExprCXX.cpp
lib/Sema/SemaInit.cpp

index d3fe6aee5c9a1b8706682e88534833e9df7deec1..285ee4945d8bf6b4730ce8639976803de92b4489 100644 (file)
@@ -621,8 +621,8 @@ TryLValueToRValueCast(Sema &Self, Expr *SrcExpr, QualType DestType,
     return TC_Failed;
   }
 
-  // FIXME: Similar to CheckReferenceInit, we actually need more AST annotation
-  // than nothing.
+  // FIXME: We should probably have an AST node for lvalue-to-rvalue 
+  // conversions.
   return TC_Success;
 }
 
index 366089f2ab633770fb7490eeb953559c299aef21..3cba68694b708ab00bf8fb9e48f1c69e3741988a 100644 (file)
@@ -2048,28 +2048,26 @@ static bool FindConditionalOverload(Sema &Self, Expr *&LHS, Expr *&RHS,
 /// handles the reference binding specially.
 static bool ConvertForConditional(Sema &Self, Expr *&E,
                                   const ImplicitConversionSequence &ICS) {
-  if (ICS.isStandard() && ICS.Standard.ReferenceBinding) {
-    assert(ICS.Standard.DirectBinding &&
+  if ((ICS.isStandard() && ICS.Standard.ReferenceBinding) ||
+      (ICS.isUserDefined() && ICS.UserDefined.After.ReferenceBinding)) {
+    assert(((ICS.isStandard() && ICS.Standard.DirectBinding) ||
+            (ICS.isUserDefined() && ICS.UserDefined.After.DirectBinding)) &&
            "TryClassUnification should never generate indirect ref bindings");
-    // FIXME: CheckReferenceInit should be able to reuse the ICS instead of
-    // redoing all the work.
-    return Self.CheckReferenceInit(E, Self.Context.getLValueReferenceType(
-                                        TargetType(ICS)),
-                                   /*FIXME:*/E->getLocStart(),
-                                   /*SuppressUserConversions=*/false,
-                                   /*AllowExplicit=*/false,
-                                   /*ForceRValue=*/false);
-  }
-  if (ICS.isUserDefined() && ICS.UserDefined.After.ReferenceBinding) {
-    assert(ICS.UserDefined.After.DirectBinding &&
-           "TryClassUnification should never generate indirect ref bindings");
-    return Self.CheckReferenceInit(E, Self.Context.getLValueReferenceType(
-                                        TargetType(ICS)),
-                                   /*FIXME:*/E->getLocStart(),
-                                   /*SuppressUserConversions=*/false,
-                                   /*AllowExplicit=*/false,
-                                   /*ForceRValue=*/false);
+    InitializedEntity Entity 
+      = InitializedEntity::InitializeTemporary(
+                         Self.Context.getLValueReferenceType(TargetType(ICS)));
+    InitializationKind Kind = InitializationKind::CreateCopy(E->getLocStart(),
+                                                             SourceLocation());
+    InitializationSequence InitSeq(Self, Entity, Kind, &E, 1);
+    Sema::OwningExprResult Result = InitSeq.Perform(Self, Entity, Kind, 
+                                      Sema::MultiExprArg(Self, (void **)&E, 1));
+    if (Result.isInvalid())
+      return true;
+    
+    E = Result.takeAs<Expr>();
+    return false;
   }
+  
   if (Self.PerformImplicitConversion(E, TargetType(ICS), ICS, Sema::AA_Converting))
     return true;
   return false;
index f86ae51c28061f77ecf33235dc6cda8c3df54aaa..aa685d172da21d25f24dd3f40ea7bfefa586d1d8 100644 (file)
@@ -3382,6 +3382,7 @@ InitializationSequence::Perform(Sema &S,
       bool IsCopy = false;
       FunctionDecl *Fn = Step->Function.Function;
       DeclAccessPair FoundFn = Step->Function.FoundDecl;
+      bool IsLvalue = false;
       if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(Fn)) {
         // Build a call to the selected constructor.
         ASTOwningVector<&ActionBase::DeleteExpr> ConstructorArgs(S);
@@ -3414,7 +3415,7 @@ InitializationSequence::Perform(Sema &S,
       } else {
         // Build a call to the conversion function.
         CXXConversionDecl *Conversion = cast<CXXConversionDecl>(Fn);
-
+        IsLvalue = Conversion->getResultType()->isLValueReferenceType();
         S.CheckMemberOperatorAccess(Kind.getLocation(), CurInitExpr, 0,
                                     FoundFn);
         
@@ -3444,7 +3445,7 @@ InitializationSequence::Perform(Sema &S,
       CurInit = S.Owned(new (S.Context) ImplicitCastExpr(CurInitExpr->getType(),
                                                          CastKind, 
                                                          CurInitExpr,
-                                                         false));
+                                                         IsLvalue));
       
       if (!IsCopy)
         CurInit = CopyIfRequiredForEntity(S, Entity, Kind, move(CurInit));