]> granicus.if.org Git - clang/commitdiff
Sema::BuildCXXMemberCallExpr() can fail due to access or ambiguities,
authorDouglas Gregor <dgregor@apple.com>
Thu, 20 Jan 2011 00:18:04 +0000 (00:18 +0000)
committerDouglas Gregor <dgregor@apple.com>
Thu, 20 Jan 2011 00:18:04 +0000 (00:18 +0000)
so allow it to propagate the failure outward. Fixes the crashing part
of <rdar://problem/8876150>.

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

include/clang/Sema/Sema.h
lib/Sema/SemaExprCXX.cpp
lib/Sema/SemaInit.cpp
lib/Sema/SemaOverload.cpp
test/SemaCXX/ambig-user-defined-conversions.cpp

index 2d48dd8cbd2cc4cd6fa48f7169f1c6d62e5c41aa..36c406476e477b13327b47309757941085a6f649 100644 (file)
@@ -2489,9 +2489,8 @@ public:
   Expr *BuildObjCEncodeExpression(SourceLocation AtLoc,
                                   TypeSourceInfo *EncodedTypeInfo,
                                   SourceLocation RParenLoc);
-  CXXMemberCallExpr *BuildCXXMemberCallExpr(Expr *Exp,
-                                            NamedDecl *FoundDecl,
-                                            CXXMethodDecl *Method);
+  ExprResult BuildCXXMemberCallExpr(Expr *Exp, NamedDecl *FoundDecl,
+                                    CXXMethodDecl *Method);
 
   ExprResult ParseObjCEncodeExpression(SourceLocation AtLoc,
                                        SourceLocation EncodeLoc,
index f7342b433e19323ad6f7e3d9e4e8577ff2513ff0..2a339142ca4acd16c0839cd3ba48739e8a21f73e 100644 (file)
@@ -1718,8 +1718,11 @@ static ExprResult BuildCXXCastArgument(Sema &S,
     
     // Create an implicit call expr that calls it.
     // FIXME: pass the FoundDecl for the user-defined conversion here
-    CXXMemberCallExpr *CE = S.BuildCXXMemberCallExpr(From, Method, Method);
-    return S.MaybeBindToTemporary(CE);
+    ExprResult Result = S.BuildCXXMemberCallExpr(From, Method, Method);
+    if (Result.isInvalid())
+      return ExprError();
+  
+    return S.MaybeBindToTemporary(Result.get());
   }
   }
 }    
@@ -3592,12 +3595,11 @@ ExprResult Sema::ActOnPseudoDestructorExpr(Scope *S, Expr *Base,
                                    Destructed, HasTrailingLParen);
 }
 
-CXXMemberCallExpr *Sema::BuildCXXMemberCallExpr(Expr *Exp, 
-                                                NamedDecl *FoundDecl,
-                                                CXXMethodDecl *Method) {
+ExprResult Sema::BuildCXXMemberCallExpr(Expr *Exp, NamedDecl *FoundDecl,
+                                        CXXMethodDecl *Method) {
   if (PerformObjectArgumentInitialization(Exp, /*Qualifier=*/0,
                                           FoundDecl, Method))
-    assert(0 && "Calling BuildCXXMemberCallExpr with invalid call?");
+    return true;
 
   MemberExpr *ME = 
       new (Context) MemberExpr(Exp, /*IsArrow=*/false, Method,
index 23b061dd4c751c16f10200a9c11ca159889ba445..9130603d560575d49ffaf1b0b4da5df13e502154 100644 (file)
@@ -3788,8 +3788,7 @@ InitializationSequence::Perform(Sema &S,
         CurInit.release();
         
         // Build the actual call to the conversion function.
-        CurInit = S.Owned(S.BuildCXXMemberCallExpr(CurInitExpr, FoundFn,
-                                                   Conversion));
+        CurInit = S.BuildCXXMemberCallExpr(CurInitExpr, FoundFn, Conversion);
         if (CurInit.isInvalid() || !CurInit.get())
           return ExprError();
         
index 0b401007b8b27796422d6445fb46206b9188327e..ac106883a3502ac2f7bc91ccad03678e15a60e79 100644 (file)
@@ -3438,7 +3438,11 @@ Sema::ConvertToIntegralOrEnumerationType(SourceLocation Loc, Expr *From,
         return ExprError();
       
       CheckMemberOperatorAccess(From->getExprLoc(), From, 0, Found);
-      From = BuildCXXMemberCallExpr(From, Found, Conversion);
+      ExprResult Result = BuildCXXMemberCallExpr(From, Found, Conversion);
+      if (Result.isInvalid())
+        return ExprError();
+      
+      From = Result.get();
     }
     
     // We'll complain below about a non-integral condition type.
@@ -3461,8 +3465,12 @@ Sema::ConvertToIntegralOrEnumerationType(SourceLocation Loc, Expr *From,
         << T << ConvTy->isEnumeralType() << ConvTy << From->getSourceRange();
     }
     
-    From = BuildCXXMemberCallExpr(From, Found,
+    ExprResult Result = BuildCXXMemberCallExpr(From, Found,
                           cast<CXXConversionDecl>(Found->getUnderlyingDecl()));
+    if (Result.isInvalid())
+      return ExprError();
+    
+    From = Result.get();
     break;
   }
     
@@ -8162,10 +8170,11 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Object,
     
     // Create an implicit member expr to refer to the conversion operator.
     // and then call it.
-    CXXMemberCallExpr *CE = BuildCXXMemberCallExpr(Object, Best->FoundDecl,
-                                                   Conv);
-      
-    return ActOnCallExpr(S, CE, LParenLoc, MultiExprArg(Args, NumArgs),
+    ExprResult Call = BuildCXXMemberCallExpr(Object, Best->FoundDecl, Conv);
+    if (Call.isInvalid())
+      return ExprError();
+    
+    return ActOnCallExpr(S, Call.get(), LParenLoc, MultiExprArg(Args, NumArgs),
                          RParenLoc);
   }
 
index dd8501adb62a858594dcbee9b6d95e2cb2ff7c7b..bf45e5d4d888addbcedcb880864a2d8b5ea75f92 100644 (file)
@@ -57,3 +57,11 @@ namespace test1 {
   }
 }
 
+namespace rdar8876150 {
+  struct A { operator bool(); };
+  struct B : A { };
+  struct C : A { };
+  struct D : B, C { };
+
+  bool f(D d) { return !d; } // expected-error{{ambiguous conversion from derived class 'rdar8876150::D' to base class 'rdar8876150::A':}}
+}