From: Douglas Gregor Date: Thu, 20 Jan 2011 00:18:04 +0000 (+0000) Subject: Sema::BuildCXXMemberCallExpr() can fail due to access or ambiguities, X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f2ae52605a49e5fc7a581f2c1ae02f1811034578;p=clang Sema::BuildCXXMemberCallExpr() can fail due to access or ambiguities, so allow it to propagate the failure outward. Fixes the crashing part of . git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@123863 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index 2d48dd8cbd..36c406476e 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -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, diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index f7342b433e..2a339142ca 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -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, diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp index 23b061dd4c..9130603d56 100644 --- a/lib/Sema/SemaInit.cpp +++ b/lib/Sema/SemaInit.cpp @@ -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(); diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp index 0b401007b8..ac106883a3 100644 --- a/lib/Sema/SemaOverload.cpp +++ b/lib/Sema/SemaOverload.cpp @@ -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(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); } diff --git a/test/SemaCXX/ambig-user-defined-conversions.cpp b/test/SemaCXX/ambig-user-defined-conversions.cpp index dd8501adb6..bf45e5d4d8 100644 --- a/test/SemaCXX/ambig-user-defined-conversions.cpp +++ b/test/SemaCXX/ambig-user-defined-conversions.cpp @@ -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':}} +}