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,
// 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());
}
}
}
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,
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();
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.
<< 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;
}
// 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);
}
}
}
+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':}}
+}