Use ExprResult& instead of Expr *& in Sema

This patch authored by Eric Niebler.

Many methods on the Sema class (e.g. ConvertPropertyForRValue) take Expr
pointers as in/out parameters (Expr *&).  This is especially true for the
routines that apply implicit conversions to nodes in-place.  This design is
workable only as long as those conversions cannot fail.  If they are allowed
to fail, they need a way to report their failures.  The typical way of doing
this in clang is to use an ExprResult, which has an extra bit to signal a
valid/invalid state.  Returning ExprResult is de riguour elsewhere in the Sema
interface.  We suggest changing the Expr *& parameters in the Sema interface
to ExprResult &.  This increases interface consistency and maintainability.

This interface change is important for work supporting MS-style C++
properties.  For reasons explained here
<http://lists.cs.uiuc.edu/pipermail/cfe-dev/2011-February/013180.html>,
seemingly trivial operations like rvalue/lvalue conversions that formerly
could not fail now can.  (The reason is that given the semantics of the
feature, getter/setter method lookup cannot happen until the point of use, at
which point it may be found that the method does not exist, or it may have the
wrong type, or overload resolution may fail, or it may be inaccessible.)

llvm-svn: 129143
This commit is contained in:
John Wiegley 2011-04-08 18:41:53 +00:00
parent 4806ff8af9
commit 0129629fd3
17 changed files with 1859 additions and 1409 deletions

View File

@ -597,6 +597,8 @@ public:
FK_ReferenceInitFailed,
/// \brief Implicit conversion failed.
FK_ConversionFailed,
/// \brief Implicit conversion failed.
FK_ConversionFromPropertyFailed,
/// \brief Too many initializers for scalar
FK_TooManyInitsForScalar,
/// \brief Reference initialization from an initializer list

View File

@ -1161,13 +1161,13 @@ public:
ExprResult PerformCopyInitialization(const InitializedEntity &Entity,
SourceLocation EqualLoc,
ExprResult Init);
bool PerformObjectArgumentInitialization(Expr *&From,
NestedNameSpecifier *Qualifier,
NamedDecl *FoundDecl,
CXXMethodDecl *Method);
ExprResult PerformObjectArgumentInitialization(Expr *From,
NestedNameSpecifier *Qualifier,
NamedDecl *FoundDecl,
CXXMethodDecl *Method);
bool PerformContextuallyConvertToBool(Expr *&From);
bool PerformContextuallyConvertToObjCId(Expr *&From);
ExprResult PerformContextuallyConvertToBool(Expr *From);
ExprResult PerformContextuallyConvertToObjCId(Expr *From);
ExprResult
ConvertToIntegralOrEnumerationType(SourceLocation Loc, Expr *FromE,
@ -1179,10 +1179,10 @@ public:
const PartialDiagnostic &AmbigNote,
const PartialDiagnostic &ConvDiag);
bool PerformObjectMemberConversion(Expr *&From,
NestedNameSpecifier *Qualifier,
NamedDecl *FoundDecl,
NamedDecl *Member);
ExprResult PerformObjectMemberConversion(Expr *From,
NestedNameSpecifier *Qualifier,
NamedDecl *FoundDecl,
NamedDecl *Member);
// Members have to be NamespaceDecl* or TranslationUnitDecl*.
// TODO: make this is a typesafe union.
@ -2049,7 +2049,7 @@ public:
const TemplateArgumentListInfo *TemplateArgs,
bool SuppressQualifierCheck = false);
ExprResult LookupMemberExpr(LookupResult &R, Expr *&Base,
ExprResult LookupMemberExpr(LookupResult &R, ExprResult &Base,
bool &IsArrow, SourceLocation OpLoc,
CXXScopeSpec &SS,
Decl *ObjCImpDecl,
@ -2474,7 +2474,7 @@ public:
//// ActOnCXXThrow - Parse throw expressions.
ExprResult ActOnCXXThrow(SourceLocation OpLoc, Expr *expr);
bool CheckCXXThrowOperand(SourceLocation ThrowLoc, Expr *&E);
ExprResult CheckCXXThrowOperand(SourceLocation ThrowLoc, Expr *E);
/// ActOnCXXTypeConstructExpr - Parse construction of a specified type.
/// Can be interpreted either as function-style casting ("int(x)")
@ -3387,10 +3387,10 @@ public:
TypeSourceInfo *Arg);
bool CheckTemplateArgumentPointerToMember(Expr *Arg,
TemplateArgument &Converted);
bool CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
QualType InstantiatedParamType, Expr *&Arg,
TemplateArgument &Converted,
CheckTemplateArgumentKind CTAK = CTAK_Specified);
ExprResult CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
QualType InstantiatedParamType, Expr *Arg,
TemplateArgument &Converted,
CheckTemplateArgumentKind CTAK = CTAK_Specified);
bool CheckTemplateArgument(TemplateTemplateParmDecl *Param,
const TemplateArgumentLoc &Arg);
@ -4745,9 +4745,9 @@ public:
/// ImpCastExprToType - If Expr is not of type 'Type', insert an implicit
/// cast. If there is already an implicit cast, merge into the existing one.
/// If isLvalue, the result of the cast is an lvalue.
void ImpCastExprToType(Expr *&Expr, QualType Type, CastKind CK,
ExprValueKind VK = VK_RValue,
const CXXCastPath *BasePath = 0);
ExprResult ImpCastExprToType(Expr *E, QualType Type, CastKind CK,
ExprValueKind VK = VK_RValue,
const CXXCastPath *BasePath = 0);
/// ScalarTypeToBooleanCastKind - Returns the cast kind corresponding
/// to the conversion from scalar type ScalarTy to the Boolean type.
@ -4756,31 +4756,31 @@ public:
/// IgnoredValueConversions - Given that an expression's result is
/// syntactically ignored, perform any conversions that are
/// required.
void IgnoredValueConversions(Expr *&expr);
ExprResult IgnoredValueConversions(Expr *E);
// UsualUnaryConversions - promotes integers (C99 6.3.1.1p2) and converts
// functions and arrays to their respective pointers (C99 6.3.2.1).
Expr *UsualUnaryConversions(Expr *&expr);
ExprResult UsualUnaryConversions(Expr *E);
// DefaultFunctionArrayConversion - converts functions and arrays
// to their respective pointers (C99 6.3.2.1).
void DefaultFunctionArrayConversion(Expr *&expr);
ExprResult DefaultFunctionArrayConversion(Expr *E);
// DefaultFunctionArrayLvalueConversion - converts functions and
// arrays to their respective pointers and performs the
// lvalue-to-rvalue conversion.
void DefaultFunctionArrayLvalueConversion(Expr *&expr);
ExprResult DefaultFunctionArrayLvalueConversion(Expr *E);
// DefaultLvalueConversion - performs lvalue-to-rvalue conversion on
// the operand. This is DefaultFunctionArrayLvalueConversion,
// except that it assumes the operand isn't of function or array
// type.
void DefaultLvalueConversion(Expr *&expr);
ExprResult DefaultLvalueConversion(Expr *E);
// DefaultArgumentPromotion (C99 6.5.2.2p6). Used for function calls that
// do not have a prototype. Integer promotions are performed on each
// argument, and arguments that have type float are promoted to double.
void DefaultArgumentPromotion(Expr *&Expr);
ExprResult DefaultArgumentPromotion(Expr *E);
// Used for emitting the right warning by DefaultVariadicArgumentPromotion
enum VariadicCallType {
@ -4803,15 +4803,15 @@ public:
// DefaultVariadicArgumentPromotion - Like DefaultArgumentPromotion, but
// will warn if the resulting type is not a POD type.
bool DefaultVariadicArgumentPromotion(Expr *&Expr, VariadicCallType CT,
FunctionDecl *FDecl);
ExprResult DefaultVariadicArgumentPromotion(Expr *E, VariadicCallType CT,
FunctionDecl *FDecl);
// UsualArithmeticConversions - performs the UsualUnaryConversions on it's
// operands and then handles various conversions that are common to binary
// operators (C99 6.3.1.8). If both operands aren't arithmetic, this
// routine returns the first non-arithmetic type found. The client is
// responsible for emitting appropriate error diagnostics.
QualType UsualArithmeticConversions(Expr *&lExpr, Expr *&rExpr,
QualType UsualArithmeticConversions(ExprResult &lExpr, ExprResult &rExpr,
bool isCompAssign = false);
/// AssignConvertType - All of the 'assignment' semantic checks return this
@ -4899,94 +4899,102 @@ public:
/// Check assignment constraints and prepare for a conversion of the
/// RHS to the LHS type.
AssignConvertType CheckAssignmentConstraints(QualType lhs, Expr *&rhs,
AssignConvertType CheckAssignmentConstraints(QualType lhs, ExprResult &rhs,
CastKind &Kind);
// CheckSingleAssignmentConstraints - Currently used by
// CheckAssignmentOperands, and ActOnReturnStmt. Prior to type checking,
// this routine performs the default function/array converions.
AssignConvertType CheckSingleAssignmentConstraints(QualType lhs,
Expr *&rExpr);
ExprResult &rExprRes);
// \brief If the lhs type is a transparent union, check whether we
// can initialize the transparent union with the given expression.
AssignConvertType CheckTransparentUnionArgumentConstraints(QualType lhs,
Expr *&rExpr);
ExprResult &rExpr);
bool IsStringLiteralToNonConstPointerConversion(Expr *From, QualType ToType);
bool CheckExceptionSpecCompatibility(Expr *From, QualType ToType);
bool PerformImplicitConversion(Expr *&From, QualType ToType,
AssignmentAction Action,
bool AllowExplicit = false);
bool PerformImplicitConversion(Expr *&From, QualType ToType,
AssignmentAction Action,
bool AllowExplicit,
ImplicitConversionSequence& ICS);
bool PerformImplicitConversion(Expr *&From, QualType ToType,
const ImplicitConversionSequence& ICS,
AssignmentAction Action,
bool CStyle = false);
bool PerformImplicitConversion(Expr *&From, QualType ToType,
const StandardConversionSequence& SCS,
AssignmentAction Action,
bool CStyle);
ExprResult PerformImplicitConversion(Expr *From, QualType ToType,
AssignmentAction Action,
bool AllowExplicit = false);
ExprResult PerformImplicitConversion(Expr *From, QualType ToType,
AssignmentAction Action,
bool AllowExplicit,
ImplicitConversionSequence& ICS);
ExprResult PerformImplicitConversion(Expr *From, QualType ToType,
const ImplicitConversionSequence& ICS,
AssignmentAction Action,
bool CStyle = false);
ExprResult PerformImplicitConversion(Expr *From, QualType ToType,
const StandardConversionSequence& SCS,
AssignmentAction Action,
bool CStyle);
/// the following "Check" methods will return a valid/converted QualType
/// or a null QualType (indicating an error diagnostic was issued).
/// type checking binary operators (subroutines of CreateBuiltinBinOp).
QualType InvalidOperands(SourceLocation l, Expr *&lex, Expr *&rex);
QualType InvalidOperands(SourceLocation l, ExprResult &lex, ExprResult &rex);
QualType CheckPointerToMemberOperands( // C++ 5.5
Expr *&lex, Expr *&rex, ExprValueKind &VK,
ExprResult &lex, ExprResult &rex, ExprValueKind &VK,
SourceLocation OpLoc, bool isIndirect);
QualType CheckMultiplyDivideOperands( // C99 6.5.5
Expr *&lex, Expr *&rex, SourceLocation OpLoc, bool isCompAssign,
ExprResult &lex, ExprResult &rex, SourceLocation OpLoc, bool isCompAssign,
bool isDivide);
QualType CheckRemainderOperands( // C99 6.5.5
Expr *&lex, Expr *&rex, SourceLocation OpLoc, bool isCompAssign = false);
ExprResult &lex, ExprResult &rex, SourceLocation OpLoc, bool isCompAssign = false);
QualType CheckAdditionOperands( // C99 6.5.6
Expr *&lex, Expr *&rex, SourceLocation OpLoc, QualType* CompLHSTy = 0);
ExprResult &lex, ExprResult &rex, SourceLocation OpLoc, QualType* CompLHSTy = 0);
QualType CheckSubtractionOperands( // C99 6.5.6
Expr *&lex, Expr *&rex, SourceLocation OpLoc, QualType* CompLHSTy = 0);
ExprResult &lex, ExprResult &rex, SourceLocation OpLoc, QualType* CompLHSTy = 0);
QualType CheckShiftOperands( // C99 6.5.7
Expr *&lex, Expr *&rex, SourceLocation OpLoc, unsigned Opc,
ExprResult &lex, ExprResult &rex, SourceLocation OpLoc, unsigned Opc,
bool isCompAssign = false);
QualType CheckCompareOperands( // C99 6.5.8/9
Expr *&lex, Expr *&rex, SourceLocation OpLoc, unsigned Opc,
ExprResult &lex, ExprResult &rex, SourceLocation OpLoc, unsigned Opc,
bool isRelational);
QualType CheckBitwiseOperands( // C99 6.5.[10...12]
Expr *&lex, Expr *&rex, SourceLocation OpLoc, bool isCompAssign = false);
ExprResult &lex, ExprResult &rex, SourceLocation OpLoc, bool isCompAssign = false);
QualType CheckLogicalOperands( // C99 6.5.[13,14]
Expr *&lex, Expr *&rex, SourceLocation OpLoc, unsigned Opc);
ExprResult &lex, ExprResult &rex, SourceLocation OpLoc, unsigned Opc);
// CheckAssignmentOperands is used for both simple and compound assignment.
// For simple assignment, pass both expressions and a null converted type.
// For compound assignment, pass both expressions and the converted type.
QualType CheckAssignmentOperands( // C99 6.5.16.[1,2]
Expr *lex, Expr *&rex, SourceLocation OpLoc, QualType convertedType);
Expr *lex, ExprResult &rex, SourceLocation OpLoc, QualType convertedType);
void ConvertPropertyForRValue(Expr *&E);
void ConvertPropertyForLValue(Expr *&LHS, Expr *&RHS, QualType& LHSTy);
void ConvertPropertyForLValue(ExprResult &LHS, ExprResult &RHS, QualType& LHSTy);
ExprResult ConvertPropertyForRValue(Expr *E);
QualType CheckConditionalOperands( // C99 6.5.15
Expr *&cond, Expr *&lhs, Expr *&rhs,
ExprResult &cond, ExprResult &lhs, ExprResult &rhs,
ExprValueKind &VK, ExprObjectKind &OK, SourceLocation questionLoc);
QualType CXXCheckConditionalOperands( // C++ 5.16
Expr *&cond, Expr *&lhs, Expr *&rhs,
ExprResult &cond, ExprResult &lhs, ExprResult &rhs,
ExprValueKind &VK, ExprObjectKind &OK, SourceLocation questionLoc);
QualType FindCompositePointerType(SourceLocation Loc, Expr *&E1, Expr *&E2,
bool *NonStandardCompositeType = 0);
QualType FindCompositePointerType(SourceLocation Loc, ExprResult &E1, ExprResult &E2,
bool *NonStandardCompositeType = 0) {
Expr *E1Tmp = E1.take(), *E2Tmp = E2.take();
QualType Composite = FindCompositePointerType(Loc, E1Tmp, E2Tmp, NonStandardCompositeType);
E1 = Owned(E1Tmp);
E2 = Owned(E2Tmp);
return Composite;
}
QualType FindCompositeObjCPointerType(Expr *&LHS, Expr *&RHS,
QualType FindCompositeObjCPointerType(ExprResult &LHS, ExprResult &RHS,
SourceLocation questionLoc);
bool DiagnoseConditionalForNull(Expr *LHS, Expr *RHS,
SourceLocation QuestionLoc);
/// type checking for vector binary operators.
QualType CheckVectorOperands(SourceLocation l, Expr *&lex, Expr *&rex);
QualType CheckVectorCompareOperands(Expr *&lex, Expr *&rx,
QualType CheckVectorOperands(SourceLocation l, ExprResult &lex, ExprResult &rex);
QualType CheckVectorCompareOperands(ExprResult &lex, ExprResult &rx,
SourceLocation l, bool isRel);
/// type checking declaration initializers (C99 6.7.8)
@ -5024,13 +5032,13 @@ public:
/// CheckCastTypes - Check type constraints for casting between types under
/// C semantics, or forward to CXXCheckCStyleCast in C++.
bool CheckCastTypes(SourceRange TyRange, QualType CastTy, Expr *&CastExpr,
CastKind &Kind, ExprValueKind &VK, CXXCastPath &BasePath,
bool FunctionalStyle = false);
ExprResult CheckCastTypes(SourceRange TyRange, QualType CastTy, Expr *CastExpr,
CastKind &Kind, ExprValueKind &VK, CXXCastPath &BasePath,
bool FunctionalStyle = false);
bool checkUnknownAnyCast(SourceRange TyRange, QualType castType,
Expr *&castExpr, CastKind &castKind,
ExprValueKind &valueKind, CXXCastPath &BasePath);
ExprResult checkUnknownAnyCast(SourceRange TyRange, QualType castType,
Expr *castExpr, CastKind &castKind,
ExprValueKind &valueKind, CXXCastPath &BasePath);
// CheckVectorCast - check type constraints for vectors.
// Since vectors are an extension, there are no C standard reference for this.
@ -5043,15 +5051,15 @@ public:
// Since vectors are an extension, there are no C standard reference for this.
// We allow casting between vectors and integer datatypes of the same size,
// or vectors and the element type of that vector.
// returns true if the cast is invalid
bool CheckExtVectorCast(SourceRange R, QualType VectorTy, Expr *&CastExpr,
CastKind &Kind);
// returns the cast expr
ExprResult CheckExtVectorCast(SourceRange R, QualType VectorTy, Expr *CastExpr,
CastKind &Kind);
/// CXXCheckCStyleCast - Check constraints of a C-style or function-style
/// cast under C++ semantics.
bool CXXCheckCStyleCast(SourceRange R, QualType CastTy, ExprValueKind &VK,
Expr *&CastExpr, CastKind &Kind,
CXXCastPath &BasePath, bool FunctionalStyle);
ExprResult CXXCheckCStyleCast(SourceRange R, QualType CastTy, ExprValueKind &VK,
Expr *CastExpr, CastKind &Kind,
CXXCastPath &BasePath, bool FunctionalStyle);
/// CheckMessageArgumentTypes - Check types in an Obj-C message send.
/// \param Method - May be null.
@ -5070,7 +5078,7 @@ public:
/// \param Loc - A location associated with the condition, e.g. the
/// 'if' keyword.
/// \return true iff there were any errors
bool CheckBooleanCondition(Expr *&CondExpr, SourceLocation Loc);
ExprResult CheckBooleanCondition(Expr *CondExpr, SourceLocation Loc);
ExprResult ActOnBooleanCondition(Scope *S, SourceLocation Loc,
Expr *SubExpr);
@ -5084,7 +5092,7 @@ public:
void DiagnoseEqualityWithExtraParens(ParenExpr *parenE);
/// CheckCXXBooleanCondition - Returns true if conversion to bool is invalid.
bool CheckCXXBooleanCondition(Expr *&CondExpr);
ExprResult CheckCXXBooleanCondition(Expr *CondExpr);
/// ConvertIntegerToTypeWarnOnOverflow - Convert the specified APInt to have
/// the specified width and sign. If an overflow occurs, detect it and emit

View File

@ -203,36 +203,36 @@ Sema::~Sema() {
/// ImpCastExprToType - If Expr is not of type 'Type', insert an implicit cast.
/// If there is already an implicit cast, merge into the existing one.
/// The result is of the given category.
void Sema::ImpCastExprToType(Expr *&Expr, QualType Ty,
CastKind Kind, ExprValueKind VK,
const CXXCastPath *BasePath) {
QualType ExprTy = Context.getCanonicalType(Expr->getType());
ExprResult Sema::ImpCastExprToType(Expr *E, QualType Ty,
CastKind Kind, ExprValueKind VK,
const CXXCastPath *BasePath) {
QualType ExprTy = Context.getCanonicalType(E->getType());
QualType TypeTy = Context.getCanonicalType(Ty);
if (ExprTy == TypeTy)
return;
return Owned(E);
// If this is a derived-to-base cast to a through a virtual base, we
// need a vtable.
if (Kind == CK_DerivedToBase &&
BasePathInvolvesVirtualBase(*BasePath)) {
QualType T = Expr->getType();
QualType T = E->getType();
if (const PointerType *Pointer = T->getAs<PointerType>())
T = Pointer->getPointeeType();
if (const RecordType *RecordTy = T->getAs<RecordType>())
MarkVTableUsed(Expr->getLocStart(),
MarkVTableUsed(E->getLocStart(),
cast<CXXRecordDecl>(RecordTy->getDecl()));
}
if (ImplicitCastExpr *ImpCast = dyn_cast<ImplicitCastExpr>(Expr)) {
if (ImplicitCastExpr *ImpCast = dyn_cast<ImplicitCastExpr>(E)) {
if (ImpCast->getCastKind() == Kind && (!BasePath || BasePath->empty())) {
ImpCast->setType(Ty);
ImpCast->setValueKind(VK);
return;
return Owned(E);
}
}
Expr = ImplicitCastExpr::Create(Context, Ty, Kind, Expr, BasePath, VK);
return Owned(ImplicitCastExpr::Create(Context, Ty, Kind, E, BasePath, VK));
}
/// ScalarTypeToBooleanCastKind - Returns the cast kind corresponding

View File

@ -42,21 +42,21 @@ enum CastType {
static void CheckConstCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
static void CheckConstCast(Sema &Self, ExprResult &SrcExpr, QualType DestType,
ExprValueKind &VK,
const SourceRange &OpRange,
const SourceRange &DestRange);
static void CheckReinterpretCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
static void CheckReinterpretCast(Sema &Self, ExprResult &SrcExpr, QualType DestType,
ExprValueKind &VK,
const SourceRange &OpRange,
const SourceRange &DestRange,
CastKind &Kind);
static void CheckStaticCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
static void CheckStaticCast(Sema &Self, ExprResult &SrcExpr, QualType DestType,
ExprValueKind &VK,
const SourceRange &OpRange,
CastKind &Kind,
CXXCastPath &BasePath);
static void CheckDynamicCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
static void CheckDynamicCast(Sema &Self, ExprResult &SrcExpr, QualType DestType,
ExprValueKind &VK,
const SourceRange &OpRange,
const SourceRange &DestRange,
@ -100,7 +100,7 @@ static TryCastResult TryStaticDowncast(Sema &Self, CanQualType SrcType,
QualType OrigDestType, unsigned &msg,
CastKind &Kind,
CXXCastPath &BasePath);
static TryCastResult TryStaticMemberPointerUpcast(Sema &Self, Expr *&SrcExpr,
static TryCastResult TryStaticMemberPointerUpcast(Sema &Self, ExprResult &SrcExpr,
QualType SrcType,
QualType DestType,bool CStyle,
const SourceRange &OpRange,
@ -108,12 +108,12 @@ static TryCastResult TryStaticMemberPointerUpcast(Sema &Self, Expr *&SrcExpr,
CastKind &Kind,
CXXCastPath &BasePath);
static TryCastResult TryStaticImplicitCast(Sema &Self, Expr *&SrcExpr,
static TryCastResult TryStaticImplicitCast(Sema &Self, ExprResult &SrcExpr,
QualType DestType, bool CStyle,
const SourceRange &OpRange,
unsigned &msg,
CastKind &Kind);
static TryCastResult TryStaticCast(Sema &Self, Expr *&SrcExpr,
static TryCastResult TryStaticCast(Sema &Self, ExprResult &SrcExpr,
QualType DestType, bool CStyle,
const SourceRange &OpRange,
unsigned &msg,
@ -121,7 +121,7 @@ static TryCastResult TryStaticCast(Sema &Self, Expr *&SrcExpr,
CXXCastPath &BasePath);
static TryCastResult TryConstCast(Sema &Self, Expr *SrcExpr, QualType DestType,
bool CStyle, unsigned &msg);
static TryCastResult TryReinterpretCast(Sema &Self, Expr *&SrcExpr,
static TryCastResult TryReinterpretCast(Sema &Self, ExprResult &SrcExpr,
QualType DestType, bool CStyle,
const SourceRange &OpRange,
unsigned &msg,
@ -148,8 +148,9 @@ Sema::ActOnCXXNamedCast(SourceLocation OpLoc, tok::TokenKind Kind,
ExprResult
Sema::BuildCXXNamedCast(SourceLocation OpLoc, tok::TokenKind Kind,
TypeSourceInfo *DestTInfo, Expr *Ex,
TypeSourceInfo *DestTInfo, Expr *E,
SourceRange AngleBrackets, SourceRange Parens) {
ExprResult Ex = Owned(E);
QualType DestType = DestTInfo->getType();
SourceRange OpRange(OpLoc, Parens.getEnd());
@ -157,11 +158,11 @@ Sema::BuildCXXNamedCast(SourceLocation OpLoc, tok::TokenKind Kind,
// If the type is dependent, we won't do the semantic analysis now.
// FIXME: should we check this in a more fine-grained manner?
bool TypeDependent = DestType->isDependentType() || Ex->isTypeDependent();
bool TypeDependent = DestType->isDependentType() || Ex.get()->isTypeDependent();
if (Ex->isBoundMemberFunction(Context))
Diag(Ex->getLocStart(), diag::err_invalid_use_of_bound_member_func)
<< Ex->getSourceRange();
if (Ex.get()->isBoundMemberFunction(Context))
Diag(Ex.get()->getLocStart(), diag::err_invalid_use_of_bound_member_func)
<< Ex.get()->getSourceRange();
ExprValueKind VK = VK_RValue;
if (TypeDependent)
@ -171,42 +172,54 @@ Sema::BuildCXXNamedCast(SourceLocation OpLoc, tok::TokenKind Kind,
default: llvm_unreachable("Unknown C++ cast!");
case tok::kw_const_cast:
if (!TypeDependent)
if (!TypeDependent) {
CheckConstCast(*this, Ex, DestType, VK, OpRange, DestRange);
if (Ex.isInvalid())
return ExprError();
}
return Owned(CXXConstCastExpr::Create(Context,
DestType.getNonLValueExprType(Context),
VK, Ex, DestTInfo, OpLoc,
VK, Ex.take(), DestTInfo, OpLoc,
Parens.getEnd()));
case tok::kw_dynamic_cast: {
CastKind Kind = CK_Dependent;
CXXCastPath BasePath;
if (!TypeDependent)
if (!TypeDependent) {
CheckDynamicCast(*this, Ex, DestType, VK, OpRange, DestRange,
Kind, BasePath);
if (Ex.isInvalid())
return ExprError();
}
return Owned(CXXDynamicCastExpr::Create(Context,
DestType.getNonLValueExprType(Context),
VK, Kind, Ex, &BasePath, DestTInfo,
VK, Kind, Ex.take(), &BasePath, DestTInfo,
OpLoc, Parens.getEnd()));
}
case tok::kw_reinterpret_cast: {
CastKind Kind = CK_Dependent;
if (!TypeDependent)
if (!TypeDependent) {
CheckReinterpretCast(*this, Ex, DestType, VK, OpRange, DestRange, Kind);
if (Ex.isInvalid())
return ExprError();
}
return Owned(CXXReinterpretCastExpr::Create(Context,
DestType.getNonLValueExprType(Context),
VK, Kind, Ex, 0,
VK, Kind, Ex.take(), 0,
DestTInfo, OpLoc, Parens.getEnd()));
}
case tok::kw_static_cast: {
CastKind Kind = CK_Dependent;
CXXCastPath BasePath;
if (!TypeDependent)
if (!TypeDependent) {
CheckStaticCast(*this, Ex, DestType, VK, OpRange, Kind, BasePath);
if (Ex.isInvalid())
return ExprError();
}
return Owned(CXXStaticCastExpr::Create(Context,
DestType.getNonLValueExprType(Context),
VK, Kind, Ex, &BasePath,
VK, Kind, Ex.take(), &BasePath,
DestTInfo, OpLoc, Parens.getEnd()));
}
}
@ -413,11 +426,11 @@ CastsAwayConstness(Sema &Self, QualType SrcType, QualType DestType) {
/// Refer to C++ 5.2.7 for details. Dynamic casts are used mostly for runtime-
/// checked downcasts in class hierarchies.
static void
CheckDynamicCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
CheckDynamicCast(Sema &Self, ExprResult &SrcExpr, QualType DestType,
ExprValueKind &VK, const SourceRange &OpRange,
const SourceRange &DestRange, CastKind &Kind,
CXXCastPath &BasePath) {
QualType OrigDestType = DestType, OrigSrcType = SrcExpr->getType();
QualType OrigDestType = DestType, OrigSrcType = SrcExpr.get()->getType();
DestType = Self.Context.getCanonicalType(DestType);
// C++ 5.2.7p1: T shall be a pointer or reference to a complete class type,
@ -464,11 +477,11 @@ CheckDynamicCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
SrcPointee = SrcPointer->getPointeeType();
} else {
Self.Diag(OpRange.getBegin(), diag::err_bad_dynamic_cast_not_ptr)
<< OrigSrcType << SrcExpr->getSourceRange();
<< OrigSrcType << SrcExpr.get()->getSourceRange();
return;
}
} else if (DestReference->isLValueReferenceType()) {
if (!SrcExpr->isLValue()) {
if (!SrcExpr.get()->isLValue()) {
Self.Diag(OpRange.getBegin(), diag::err_bad_cxx_cast_rvalue)
<< CT_Dynamic << OrigSrcType << OrigDestType << OpRange;
}
@ -481,11 +494,11 @@ CheckDynamicCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
if (SrcRecord) {
if (Self.RequireCompleteType(OpRange.getBegin(), SrcPointee,
Self.PDiag(diag::err_bad_dynamic_cast_incomplete)
<< SrcExpr->getSourceRange()))
<< SrcExpr.get()->getSourceRange()))
return;
} else {
Self.Diag(OpRange.getBegin(), diag::err_bad_dynamic_cast_not_class)
<< SrcPointee.getUnqualifiedType() << SrcExpr->getSourceRange();
<< SrcPointee.getUnqualifiedType() << SrcExpr.get()->getSourceRange();
return;
}
@ -532,7 +545,7 @@ CheckDynamicCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
assert(SrcDecl && "Definition missing");
if (!cast<CXXRecordDecl>(SrcDecl)->isPolymorphic()) {
Self.Diag(OpRange.getBegin(), diag::err_bad_dynamic_cast_not_polymorphic)
<< SrcPointee.getUnqualifiedType() << SrcExpr->getSourceRange();
<< SrcPointee.getUnqualifiedType() << SrcExpr.get()->getSourceRange();
}
Self.MarkVTableUsed(OpRange.getBegin(),
cast<CXXRecordDecl>(SrcRecord->getDecl()));
@ -547,17 +560,20 @@ CheckDynamicCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
/// const char *str = "literal";
/// legacy_function(const_cast\<char*\>(str));
void
CheckConstCast(Sema &Self, Expr *&SrcExpr, QualType DestType, ExprValueKind &VK,
CheckConstCast(Sema &Self, ExprResult &SrcExpr, QualType DestType, ExprValueKind &VK,
const SourceRange &OpRange, const SourceRange &DestRange) {
VK = Expr::getValueKindForType(DestType);
if (VK == VK_RValue)
Self.DefaultFunctionArrayLvalueConversion(SrcExpr);
if (VK == VK_RValue) {
SrcExpr = Self.DefaultFunctionArrayLvalueConversion(SrcExpr.take());
if (SrcExpr.isInvalid()) // if conversion failed, don't report another error
return;
}
unsigned msg = diag::err_bad_cxx_cast_generic;
if (TryConstCast(Self, SrcExpr, DestType, /*CStyle*/false, msg) != TC_Success
if (TryConstCast(Self, SrcExpr.get(), DestType, /*CStyle*/false, msg) != TC_Success
&& msg != 0)
Self.Diag(OpRange.getBegin(), msg) << CT_Const
<< SrcExpr->getType() << DestType << OpRange;
<< SrcExpr.get()->getType() << DestType << OpRange;
}
/// CheckReinterpretCast - Check that a reinterpret_cast\<DestType\>(SrcExpr) is
@ -566,27 +582,32 @@ CheckConstCast(Sema &Self, Expr *&SrcExpr, QualType DestType, ExprValueKind &VK,
/// like this:
/// char *bytes = reinterpret_cast\<char*\>(int_ptr);
void
CheckReinterpretCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
CheckReinterpretCast(Sema &Self, ExprResult &SrcExpr, QualType DestType,
ExprValueKind &VK, const SourceRange &OpRange,
const SourceRange &DestRange, CastKind &Kind) {
VK = Expr::getValueKindForType(DestType);
if (VK == VK_RValue)
Self.DefaultFunctionArrayLvalueConversion(SrcExpr);
if (VK == VK_RValue) {
SrcExpr = Self.DefaultFunctionArrayLvalueConversion(SrcExpr.take());
if (SrcExpr.isInvalid()) // if conversion failed, don't report another error
return;
}
unsigned msg = diag::err_bad_cxx_cast_generic;
if (TryReinterpretCast(Self, SrcExpr, DestType, /*CStyle*/false, OpRange,
msg, Kind)
!= TC_Success && msg != 0)
{
if (SrcExpr->getType() == Self.Context.OverloadTy) {
if (SrcExpr.isInvalid()) // if conversion failed, don't report another error
return;
if (SrcExpr.get()->getType() == Self.Context.OverloadTy) {
//FIXME: &f<int>; is overloaded and resolvable
Self.Diag(OpRange.getBegin(), diag::err_bad_reinterpret_cast_overload)
<< OverloadExpr::find(SrcExpr).Expression->getName()
<< OverloadExpr::find(SrcExpr.get()).Expression->getName()
<< DestType << OpRange;
Self.NoteAllOverloadCandidates(SrcExpr);
Self.NoteAllOverloadCandidates(SrcExpr.get());
} else {
diagnoseBadCast(Self, msg, CT_Reinterpret, OpRange, SrcExpr, DestType);
diagnoseBadCast(Self, msg, CT_Reinterpret, OpRange, SrcExpr.get(), DestType);
}
}
}
@ -596,23 +617,25 @@ CheckReinterpretCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
/// Refer to C++ 5.2.9 for details. Static casts are mostly used for making
/// implicit conversions explicit and getting rid of data loss warnings.
void
CheckStaticCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
CheckStaticCast(Sema &Self, ExprResult &SrcExpr, QualType DestType,
ExprValueKind &VK, const SourceRange &OpRange,
CastKind &Kind, CXXCastPath &BasePath) {
// This test is outside everything else because it's the only case where
// a non-lvalue-reference target type does not lead to decay.
// C++ 5.2.9p4: Any expression can be explicitly converted to type "cv void".
if (DestType->isVoidType()) {
Self.IgnoredValueConversions(SrcExpr);
if (SrcExpr->getType() == Self.Context.OverloadTy) {
SrcExpr = Self.IgnoredValueConversions(SrcExpr.take());
if (SrcExpr.isInvalid()) // if conversion failed, don't report another error
return;
if (SrcExpr.get()->getType() == Self.Context.OverloadTy) {
ExprResult SingleFunctionExpression =
Self.ResolveAndFixSingleFunctionTemplateSpecialization(SrcExpr,
Self.ResolveAndFixSingleFunctionTemplateSpecialization(SrcExpr.get(),
false, // Decay Function to ptr
true, // Complain
OpRange, DestType, diag::err_bad_static_cast_overload);
if (SingleFunctionExpression.isUsable())
{
SrcExpr = SingleFunctionExpression.release();
SrcExpr = SingleFunctionExpression;
Kind = CK_ToVoid;
}
}
@ -622,30 +645,35 @@ CheckStaticCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
}
VK = Expr::getValueKindForType(DestType);
if (VK == VK_RValue && !DestType->isRecordType())
Self.DefaultFunctionArrayLvalueConversion(SrcExpr);
if (VK == VK_RValue && !DestType->isRecordType()) {
SrcExpr = Self.DefaultFunctionArrayLvalueConversion(SrcExpr.take());
if (SrcExpr.isInvalid()) // if conversion failed, don't report another error
return;
}
unsigned msg = diag::err_bad_cxx_cast_generic;
if (TryStaticCast(Self, SrcExpr, DestType, /*CStyle*/false, OpRange, msg,
Kind, BasePath) != TC_Success && msg != 0) {
if (SrcExpr->getType() == Self.Context.OverloadTy) {
OverloadExpr* oe = OverloadExpr::find(SrcExpr).Expression;
if (SrcExpr.isInvalid())
return;
if (SrcExpr.get()->getType() == Self.Context.OverloadTy) {
OverloadExpr* oe = OverloadExpr::find(SrcExpr.get()).Expression;
Self.Diag(OpRange.getBegin(), diag::err_bad_static_cast_overload)
<< oe->getName() << DestType << OpRange
<< oe->getQualifierLoc().getSourceRange();
Self.NoteAllOverloadCandidates(SrcExpr);
Self.NoteAllOverloadCandidates(SrcExpr.get());
} else {
diagnoseBadCast(Self, msg, CT_Static, OpRange, SrcExpr, DestType);
diagnoseBadCast(Self, msg, CT_Static, OpRange, SrcExpr.get(), DestType);
}
}
else if (Kind == CK_BitCast)
Self.CheckCastAlign(SrcExpr, DestType, OpRange);
Self.CheckCastAlign(SrcExpr.get(), DestType, OpRange);
}
/// TryStaticCast - Check if a static cast can be performed, and do so if
/// possible. If @p CStyle, ignore access restrictions on hierarchy casting
/// and casting away constness.
static TryCastResult TryStaticCast(Sema &Self, Expr *&SrcExpr,
static TryCastResult TryStaticCast(Sema &Self, ExprResult &SrcExpr,
QualType DestType, bool CStyle,
const SourceRange &OpRange, unsigned &msg,
CastKind &Kind,
@ -670,7 +698,7 @@ static TryCastResult TryStaticCast(Sema &Self, Expr *&SrcExpr,
// C++ 5.2.9p5, reference downcast.
// See the function for details.
// DR 427 specifies that this is to be applied before paragraph 2.
tcr = TryStaticReferenceDowncast(Self, SrcExpr, DestType, CStyle, OpRange,
tcr = TryStaticReferenceDowncast(Self, SrcExpr.get(), DestType, CStyle, OpRange,
msg, Kind, BasePath);
if (tcr != TC_NotApplicable)
return tcr;
@ -678,7 +706,7 @@ static TryCastResult TryStaticCast(Sema &Self, Expr *&SrcExpr,
// C++0x [expr.static.cast]p3:
// A glvalue of type "cv1 T1" can be cast to type "rvalue reference to cv2
// T2" if "cv2 T2" is reference-compatible with "cv1 T1".
tcr = TryLValueToRValueCast(Self, SrcExpr, DestType, CStyle, Kind, BasePath,
tcr = TryLValueToRValueCast(Self, SrcExpr.get(), DestType, CStyle, Kind, BasePath,
msg);
if (tcr != TC_NotApplicable)
return tcr;
@ -687,6 +715,8 @@ static TryCastResult TryStaticCast(Sema &Self, Expr *&SrcExpr,
// [...] if the declaration "T t(e);" is well-formed, [...].
tcr = TryStaticImplicitCast(Self, SrcExpr, DestType, CStyle, OpRange, msg,
Kind);
if (SrcExpr.isInvalid())
return TC_Failed;
if (tcr != TC_NotApplicable)
return tcr;
@ -698,7 +728,7 @@ static TryCastResult TryStaticCast(Sema &Self, Expr *&SrcExpr,
// In the CStyle case, the earlier attempt to const_cast should have taken
// care of reverse qualification conversions.
QualType SrcType = Self.Context.getCanonicalType(SrcExpr->getType());
QualType SrcType = Self.Context.getCanonicalType(SrcExpr.get()->getType());
// C++0x 5.2.9p9: A value of a scoped enumeration type can be explicitly
// converted to an integral type. [...] A value of a scoped enumeration type
@ -1028,7 +1058,7 @@ TryStaticDowncast(Sema &Self, CanQualType SrcType, CanQualType DestType,
/// where B is a base class of D [...].
///
TryCastResult
TryStaticMemberPointerUpcast(Sema &Self, Expr *&SrcExpr, QualType SrcType,
TryStaticMemberPointerUpcast(Sema &Self, ExprResult &SrcExpr, QualType SrcType,
QualType DestType, bool CStyle,
const SourceRange &OpRange,
unsigned &msg, CastKind &Kind,
@ -1039,9 +1069,9 @@ TryStaticMemberPointerUpcast(Sema &Self, Expr *&SrcExpr, QualType SrcType,
bool WasOverloadedFunction = false;
DeclAccessPair FoundOverload;
if (SrcExpr->getType() == Self.Context.OverloadTy) {
if (SrcExpr.get()->getType() == Self.Context.OverloadTy) {
if (FunctionDecl *Fn
= Self.ResolveAddressOfOverloadedFunction(SrcExpr, DestType, false,
= Self.ResolveAddressOfOverloadedFunction(SrcExpr.get(), DestType, false,
FoundOverload)) {
CXXMethodDecl *M = cast<CXXMethodDecl>(Fn);
SrcType = Self.Context.getMemberPointerType(Fn->getType(),
@ -1112,7 +1142,7 @@ TryStaticMemberPointerUpcast(Sema &Self, Expr *&SrcExpr, QualType SrcType,
if (WasOverloadedFunction) {
// Resolve the address of the overloaded function again, this time
// allowing complaints if something goes wrong.
FunctionDecl *Fn = Self.ResolveAddressOfOverloadedFunction(SrcExpr,
FunctionDecl *Fn = Self.ResolveAddressOfOverloadedFunction(SrcExpr.get(),
DestType,
true,
FoundOverload);
@ -1122,7 +1152,7 @@ TryStaticMemberPointerUpcast(Sema &Self, Expr *&SrcExpr, QualType SrcType,
}
SrcExpr = Self.FixOverloadedFunctionReference(SrcExpr, FoundOverload, Fn);
if (!SrcExpr) {
if (!SrcExpr.isUsable()) {
msg = 0;
return TC_Failed;
}
@ -1139,7 +1169,7 @@ TryStaticMemberPointerUpcast(Sema &Self, Expr *&SrcExpr, QualType SrcType,
/// An expression e can be explicitly converted to a type T using a
/// @c static_cast if the declaration "T t(e);" is well-formed [...].
TryCastResult
TryStaticImplicitCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
TryStaticImplicitCast(Sema &Self, ExprResult &SrcExpr, QualType DestType,
bool CStyle, const SourceRange &OpRange, unsigned &msg,
CastKind &Kind) {
if (DestType->isRecordType()) {
@ -1153,7 +1183,8 @@ TryStaticImplicitCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
InitializedEntity Entity = InitializedEntity::InitializeTemporary(DestType);
InitializationKind InitKind
= InitializationKind::CreateCast(/*FIXME:*/OpRange, CStyle);
InitializationSequence InitSeq(Self, Entity, InitKind, &SrcExpr, 1);
Expr *SrcExprRaw = SrcExpr.get();
InitializationSequence InitSeq(Self, Entity, InitKind, &SrcExprRaw, 1);
// At this point of CheckStaticCast, if the destination is a reference,
// or the expression is an overload expression this has to work.
@ -1166,7 +1197,7 @@ TryStaticImplicitCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
return TC_NotApplicable;
ExprResult Result
= InitSeq.Perform(Self, Entity, InitKind, MultiExprArg(Self, &SrcExpr, 1));
= InitSeq.Perform(Self, Entity, InitKind, MultiExprArg(Self, &SrcExprRaw, 1));
if (Result.isInvalid()) {
msg = 0;
return TC_Failed;
@ -1177,7 +1208,7 @@ TryStaticImplicitCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
else
Kind = CK_NoOp;
SrcExpr = Result.takeAs<Expr>();
SrcExpr = move(Result);
return TC_Success;
}
@ -1250,9 +1281,7 @@ static TryCastResult TryConstCast(Sema &Self, Expr *SrcExpr, QualType DestType,
}
static TryCastResult TryReinterpretCast(Sema &Self, Expr *&SrcExpr,
static TryCastResult TryReinterpretCast(Sema &Self, ExprResult &SrcExpr,
QualType DestType, bool CStyle,
const SourceRange &OpRange,
unsigned &msg,
@ -1260,19 +1289,19 @@ static TryCastResult TryReinterpretCast(Sema &Self, Expr *&SrcExpr,
bool IsLValueCast = false;
DestType = Self.Context.getCanonicalType(DestType);
QualType SrcType = SrcExpr->getType();
QualType SrcType = SrcExpr.get()->getType();
// Is the source an overloaded name? (i.e. &foo)
// If so, reinterpret_cast can not help us here (13.4, p1, bullet 5) ...
if (SrcType == Self.Context.OverloadTy) {
// ... unless foo<int> resolves to an lvalue unambiguously
ExprResult SingleFunctionExpr =
Self.ResolveAndFixSingleFunctionTemplateSpecialization(SrcExpr,
Self.ResolveAndFixSingleFunctionTemplateSpecialization(SrcExpr.get(),
Expr::getValueKindForType(DestType) == VK_RValue // Convert Fun to Ptr
);
if (SingleFunctionExpr.isUsable()) {
SrcExpr = SingleFunctionExpr.release();
SrcType = SrcExpr->getType();
SrcExpr = move(SingleFunctionExpr);
SrcType = SrcExpr.get()->getType();
}
else
return TC_NotApplicable;
@ -1280,7 +1309,7 @@ static TryCastResult TryReinterpretCast(Sema &Self, Expr *&SrcExpr,
if (const ReferenceType *DestTypeTmp = DestType->getAs<ReferenceType>()) {
bool LValue = DestTypeTmp->isLValueReferenceType();
if (LValue && !SrcExpr->isLValue()) {
if (LValue && !SrcExpr.get()->isLValue()) {
// Cannot cast non-lvalue to lvalue reference type. See the similar
// comment in const_cast.
msg = diag::err_bad_cxx_cast_rvalue;
@ -1482,21 +1511,25 @@ static TryCastResult TryReinterpretCast(Sema &Self, Expr *&SrcExpr,
return TC_Success;
}
bool
ExprResult
Sema::CXXCheckCStyleCast(SourceRange R, QualType CastTy, ExprValueKind &VK,
Expr *&CastExpr, CastKind &Kind,
Expr *CastExpr, CastKind &Kind,
CXXCastPath &BasePath,
bool FunctionalStyle) {
if (CastExpr->isBoundMemberFunction(Context))
return Diag(CastExpr->getLocStart(),
diag::err_invalid_use_of_bound_member_func)
if (CastExpr->isBoundMemberFunction(Context)) {
Diag(CastExpr->getLocStart(), diag::err_invalid_use_of_bound_member_func)
<< CastExpr->getSourceRange();
return ExprError();
}
// This test is outside everything else because it's the only case where
// a non-lvalue-reference target type does not lead to decay.
// C++ 5.2.9p4: Any expression can be explicitly converted to type "cv void".
if (CastTy->isVoidType()) {
IgnoredValueConversions(CastExpr);
ExprResult CastExprRes = IgnoredValueConversions(CastExpr);
if (CastExprRes.isInvalid())
return ExprError();
CastExpr = CastExprRes.take();
bool ret = false; // false is 'able to convert'
if (CastExpr->getType() == Context.OverloadTy) {
ExprResult SingleFunctionExpr =
@ -1506,7 +1539,7 @@ Sema::CXXCheckCStyleCast(SourceRange R, QualType CastTy, ExprValueKind &VK,
diag::err_bad_cstyle_cast_overload);
if (SingleFunctionExpr.isUsable()) {
CastExpr = SingleFunctionExpr.release();
CastExpr = SingleFunctionExpr.take();
Kind = CK_ToVoid;
}
else
@ -1514,7 +1547,7 @@ Sema::CXXCheckCStyleCast(SourceRange R, QualType CastTy, ExprValueKind &VK,
}
else
Kind = CK_ToVoid;
return ret;
return ret ? ExprError() : Owned(CastExpr);
}
// Case of AltiVec vector initialization with a single literal
@ -1524,7 +1557,7 @@ Sema::CXXCheckCStyleCast(SourceRange R, QualType CastTy, ExprValueKind &VK,
&& (CastExpr->getType()->isIntegerType()
|| CastExpr->getType()->isFloatingType())) {
Kind = CK_VectorSplat;
return false;
return Owned(CastExpr);
}
// Make sure we determine the value kind before we bail out for
@ -1534,11 +1567,15 @@ Sema::CXXCheckCStyleCast(SourceRange R, QualType CastTy, ExprValueKind &VK,
// If the type is dependent, we won't do any other semantic analysis now.
if (CastTy->isDependentType() || CastExpr->isTypeDependent()) {
Kind = CK_Dependent;
return false;
return Owned(CastExpr);
}
if (VK == VK_RValue && !CastTy->isRecordType())
DefaultFunctionArrayLvalueConversion(CastExpr);
if (VK == VK_RValue && !CastTy->isRecordType()) {
ExprResult CastExprRes = DefaultFunctionArrayLvalueConversion(CastExpr);
if (CastExprRes.isInvalid())
return ExprError();
CastExpr = CastExprRes.take();
}
// C++ [expr.cast]p5: The conversions performed by
// - a const_cast,
@ -1559,19 +1596,27 @@ Sema::CXXCheckCStyleCast(SourceRange R, QualType CastTy, ExprValueKind &VK,
if (tcr == TC_NotApplicable) {
// ... or if that is not possible, a static_cast, ignoring const, ...
tcr = TryStaticCast(*this, CastExpr, CastTy, /*CStyle*/true, R, msg, Kind,
ExprResult CastExprRes = Owned(CastExpr);
tcr = TryStaticCast(*this, CastExprRes, CastTy, /*CStyle*/true, R, msg, Kind,
BasePath);
if (CastExprRes.isInvalid())
return ExprError();
CastExpr = CastExprRes.take();
if (tcr == TC_NotApplicable) {
// ... and finally a reinterpret_cast, ignoring const.
tcr = TryReinterpretCast(*this, CastExpr, CastTy, /*CStyle*/true, R, msg,
CastExprRes = Owned(CastExpr);
tcr = TryReinterpretCast(*this, CastExprRes, CastTy, /*CStyle*/true, R, msg,
Kind);
if (CastExprRes.isInvalid())
return ExprError();
CastExpr = CastExprRes.take();
}
}
if (tcr != TC_Success && msg != 0) {
if (CastExpr->getType() == Context.OverloadTy) {
DeclAccessPair Found;
FunctionDecl *Fn = ResolveAddressOfOverloadedFunction(CastExpr,
FunctionDecl *Fn = ResolveAddressOfOverloadedFunction(CastExpr,
CastTy,
/* Complain */ true,
Found);
@ -1588,6 +1633,9 @@ Sema::CXXCheckCStyleCast(SourceRange R, QualType CastTy, ExprValueKind &VK,
else if (Kind == CK_BitCast)
CheckCastAlign(CastExpr, CastTy, R);
return tcr != TC_Success;
if (tcr != TC_Success)
return ExprError();
return Owned(CastExpr);
}

View File

@ -492,14 +492,14 @@ Sema::SemaBuiltinAtomicOverloaded(ExprResult TheCallResult) {
// deduce the types of the rest of the arguments accordingly. Walk
// the remaining arguments, converting them to the deduced value type.
for (unsigned i = 0; i != NumFixed; ++i) {
Expr *Arg = TheCall->getArg(i+1);
ExprResult Arg = TheCall->getArg(i+1);
// If the argument is an implicit cast, then there was a promotion due to
// "...", just remove it now.
if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Arg)) {
if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Arg.get())) {
Arg = ICE->getSubExpr();
ICE->setSubExpr(0);
TheCall->setArg(i+1, Arg);
TheCall->setArg(i+1, Arg.get());
}
// GCC does an implicit conversion to the pointer or integer ValType. This
@ -507,7 +507,8 @@ Sema::SemaBuiltinAtomicOverloaded(ExprResult TheCallResult) {
CastKind Kind = CK_Invalid;
ExprValueKind VK = VK_RValue;
CXXCastPath BasePath;
if (CheckCastTypes(Arg->getSourceRange(), ValType, Arg, Kind, VK, BasePath))
Arg = CheckCastTypes(Arg.get()->getSourceRange(), ValType, Arg.take(), Kind, VK, BasePath);
if (Arg.isInvalid())
return ExprError();
// Okay, we have something that *can* be converted to the right type. Check
@ -516,8 +517,8 @@ Sema::SemaBuiltinAtomicOverloaded(ExprResult TheCallResult) {
// pass in 42. The 42 gets converted to char. This is even more strange
// for things like 45.123 -> char, etc.
// FIXME: Do this check.
ImpCastExprToType(Arg, ValType, Kind, VK, &BasePath);
TheCall->setArg(i+1, Arg);
Arg = ImpCastExprToType(Arg.take(), ValType, Kind, VK, &BasePath);
TheCall->setArg(i+1, Arg.get());
}
// Switch the DeclRefExpr to refer to the new decl.
@ -526,9 +527,10 @@ Sema::SemaBuiltinAtomicOverloaded(ExprResult TheCallResult) {
// Set the callee in the CallExpr.
// FIXME: This leaks the original parens and implicit casts.
Expr *PromotedCall = DRE;
UsualUnaryConversions(PromotedCall);
TheCall->setCallee(PromotedCall);
ExprResult PromotedCall = UsualUnaryConversions(DRE);
if (PromotedCall.isInvalid())
return ExprError();
TheCall->setCallee(PromotedCall.take());
// Change the result type of the call to match the original value type. This
// is arbitrary, but the codegen for these builtins ins design to handle it
@ -645,29 +647,31 @@ bool Sema::SemaBuiltinUnorderedCompare(CallExpr *TheCall) {
<< SourceRange(TheCall->getArg(2)->getLocStart(),
(*(TheCall->arg_end()-1))->getLocEnd());
Expr *OrigArg0 = TheCall->getArg(0);
Expr *OrigArg1 = TheCall->getArg(1);
ExprResult OrigArg0 = TheCall->getArg(0);
ExprResult OrigArg1 = TheCall->getArg(1);
// Do standard promotions between the two arguments, returning their common
// type.
QualType Res = UsualArithmeticConversions(OrigArg0, OrigArg1, false);
if (OrigArg0.isInvalid() || OrigArg1.isInvalid())
return true;
// Make sure any conversions are pushed back into the call; this is
// type safe since unordered compare builtins are declared as "_Bool
// foo(...)".
TheCall->setArg(0, OrigArg0);
TheCall->setArg(1, OrigArg1);
TheCall->setArg(0, OrigArg0.get());
TheCall->setArg(1, OrigArg1.get());
if (OrigArg0->isTypeDependent() || OrigArg1->isTypeDependent())
if (OrigArg0.get()->isTypeDependent() || OrigArg1.get()->isTypeDependent())
return false;
// If the common type isn't a real floating type, then the arguments were
// invalid for this operation.
if (!Res->isRealFloatingType())
return Diag(OrigArg0->getLocStart(),
return Diag(OrigArg0.get()->getLocStart(),
diag::err_typecheck_call_invalid_ordered_compare)
<< OrigArg0->getType() << OrigArg1->getType()
<< SourceRange(OrigArg0->getLocStart(), OrigArg1->getLocEnd());
<< OrigArg0.get()->getType() << OrigArg1.get()->getType()
<< SourceRange(OrigArg0.get()->getLocStart(), OrigArg1.get()->getLocEnd());
return false;
}

View File

@ -4816,8 +4816,12 @@ void Sema::CodeCompleteObjCInstanceMessage(Scope *S, ExprTy *Receiver,
// If necessary, apply function/array conversion to the receiver.
// C99 6.7.5.3p[7,8].
if (RecExpr)
DefaultFunctionArrayLvalueConversion(RecExpr);
if (RecExpr) {
ExprResult Conv = DefaultFunctionArrayLvalueConversion(RecExpr);
if (Conv.isInvalid()) // conversion failed. bail.
return;
RecExpr = Conv.take();
}
QualType ReceiverType = RecExpr? RecExpr->getType()
: Super? Context.getObjCObjectPointerType(
Context.getObjCInterfaceType(Super))

View File

@ -7783,7 +7783,7 @@ EnumConstantDecl *Sema::CheckEnumConstant(EnumDecl *Enum,
<< (EnumVal.isUnsigned() || EnumVal.isNonNegative());
else if (!Context.hasSameType(Val->getType(), Context.IntTy)) {
// Force the type of the expression to 'int'.
ImpCastExprToType(Val, Context.IntTy, CK_IntegralCast);
Val = ImpCastExprToType(Val, Context.IntTy, CK_IntegralCast).take();
}
}
@ -7796,12 +7796,12 @@ EnumConstantDecl *Sema::CheckEnumConstant(EnumDecl *Enum,
if (!isRepresentableIntegerValue(Context, EnumVal, EltTy)) {
if (getLangOptions().Microsoft) {
Diag(IdLoc, diag::ext_enumerator_too_large) << EltTy;
ImpCastExprToType(Val, EltTy, CK_IntegralCast);
Val = ImpCastExprToType(Val, EltTy, CK_IntegralCast).take();
} else
Diag(IdLoc, diag::err_enumerator_too_large)
<< EltTy;
} else
ImpCastExprToType(Val, EltTy, CK_IntegralCast);
Val = ImpCastExprToType(Val, EltTy, CK_IntegralCast).take();
}
else {
// C++0x [dcl.enum]p5:

View File

@ -1765,9 +1765,9 @@ BuildImplicitBaseInitializer(Sema &SemaRef, CXXConstructorDecl *Constructor,
CXXCastPath BasePath;
BasePath.push_back(BaseSpec);
SemaRef.ImpCastExprToType(CopyCtorArg, ArgTy,
CK_UncheckedDerivedToBase,
VK_LValue, &BasePath);
CopyCtorArg = SemaRef.ImpCastExprToType(CopyCtorArg, ArgTy,
CK_UncheckedDerivedToBase,
VK_LValue, &BasePath).take();
InitializationKind InitKind
= InitializationKind::CreateDirect(Constructor->getLocation(),
@ -5603,21 +5603,19 @@ void Sema::DefineImplicitCopyAssignment(SourceLocation CurrentLocation,
// Construct the "from" expression, which is an implicit cast to the
// appropriately-qualified base type.
Expr *From = OtherRef;
ImpCastExprToType(From, Context.getQualifiedType(BaseType, OtherQuals),
CK_UncheckedDerivedToBase,
VK_LValue, &BasePath);
From = ImpCastExprToType(From, Context.getQualifiedType(BaseType, OtherQuals),
CK_UncheckedDerivedToBase,
VK_LValue, &BasePath).take();
// Dereference "this".
ExprResult To = CreateBuiltinUnaryOp(Loc, UO_Deref, This);
// Implicitly cast "this" to the appropriately-qualified base type.
Expr *ToE = To.takeAs<Expr>();
ImpCastExprToType(ToE,
Context.getCVRQualifiedType(BaseType,
CopyAssignOperator->getTypeQualifiers()),
CK_UncheckedDerivedToBase,
VK_LValue, &BasePath);
To = Owned(ToE);
To = ImpCastExprToType(To.take(),
Context.getCVRQualifiedType(BaseType,
CopyAssignOperator->getTypeQualifiers()),
CK_UncheckedDerivedToBase,
VK_LValue, &BasePath);
// Build the copy.
StmtResult Copy = BuildSingleCopyAssign(*this, Loc, BaseType,

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -246,7 +246,10 @@ bool Sema::CheckMessageArgumentTypes(Expr **Args, unsigned NumArgs,
if (Args[i]->isTypeDependent())
continue;
DefaultArgumentPromotion(Args[i]);
ExprResult Result = DefaultArgumentPromotion(Args[i]);
if (Result.isInvalid())
return true;
Args[i] = Result.take();
}
unsigned DiagID = isClassMessage ? diag::warn_class_method_not_found :
@ -305,7 +308,9 @@ bool Sema::CheckMessageArgumentTypes(Expr **Args, unsigned NumArgs,
if (Args[i]->isTypeDependent())
continue;
IsError |= DefaultVariadicArgumentPromotion(Args[i], VariadicMethod, 0);
ExprResult Arg = DefaultVariadicArgumentPromotion(Args[i], VariadicMethod, 0);
IsError |= Arg.isInvalid();
Args[i] = Arg.take();
}
} else {
// Check for extra arguments to non-variadic methods.
@ -1040,7 +1045,10 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver,
// If necessary, apply function/array conversion to the receiver.
// C99 6.7.5.3p[7,8].
DefaultFunctionArrayLvalueConversion(Receiver);
ExprResult Result = DefaultFunctionArrayLvalueConversion(Receiver);
if (Result.isInvalid())
return ExprError();
Receiver = Result.take();
ReceiverType = Receiver->getType();
}
@ -1162,37 +1170,42 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver,
<< ReceiverType
<< Receiver->getSourceRange();
if (ReceiverType->isPointerType())
ImpCastExprToType(Receiver, Context.getObjCIdType(),
CK_BitCast);
Receiver = ImpCastExprToType(Receiver, Context.getObjCIdType(),
CK_BitCast).take();
else {
// TODO: specialized warning on null receivers?
bool IsNull = Receiver->isNullPointerConstant(Context,
Expr::NPC_ValueDependentIsNull);
ImpCastExprToType(Receiver, Context.getObjCIdType(),
IsNull ? CK_NullToPointer : CK_IntegralToPointer);
Receiver = ImpCastExprToType(Receiver, Context.getObjCIdType(),
IsNull ? CK_NullToPointer : CK_IntegralToPointer).take();
}
ReceiverType = Receiver->getType();
}
else if (getLangOptions().CPlusPlus &&
!PerformContextuallyConvertToObjCId(Receiver)) {
if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Receiver)) {
Receiver = ICE->getSubExpr();
ReceiverType = Receiver->getType();
else {
ExprResult ReceiverRes;
if (getLangOptions().CPlusPlus)
ReceiverRes = PerformContextuallyConvertToObjCId(Receiver);
if (ReceiverRes.isUsable()) {
Receiver = ReceiverRes.take();
if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Receiver)) {
Receiver = ICE->getSubExpr();
ReceiverType = Receiver->getType();
}
return BuildInstanceMessage(Receiver,
ReceiverType,
SuperLoc,
Sel,
Method,
LBracLoc,
SelectorLoc,
RBracLoc,
move(ArgsIn));
} else {
// Reject other random receiver types (e.g. structs).
Diag(Loc, diag::err_bad_receiver_type)
<< ReceiverType << Receiver->getSourceRange();
return ExprError();
}
return BuildInstanceMessage(Receiver,
ReceiverType,
SuperLoc,
Sel,
Method,
LBracLoc,
SelectorLoc,
RBracLoc,
move(ArgsIn));
} else {
// Reject other random receiver types (e.g. structs).
Diag(Loc, diag::err_bad_receiver_type)
<< ReceiverType << Receiver->getSourceRange();
return ExprError();
}
}
}

View File

@ -713,15 +713,23 @@ void InitListChecker::CheckSubElementType(const InitializedEntity &Entity,
// compatible structure or union type. In the latter case, the
// initial value of the object, including unnamed members, is
// that of the expression.
ExprResult ExprRes = SemaRef.Owned(expr);
if ((ElemType->isRecordType() || ElemType->isVectorType()) &&
SemaRef.CheckSingleAssignmentConstraints(ElemType, expr)
SemaRef.CheckSingleAssignmentConstraints(ElemType, ExprRes)
== Sema::Compatible) {
SemaRef.DefaultFunctionArrayLvalueConversion(expr);
UpdateStructuredListElement(StructuredList, StructuredIndex, expr);
if (ExprRes.isInvalid())
hadError = true;
else {
ExprRes = SemaRef.DefaultFunctionArrayLvalueConversion(ExprRes.take());
if (ExprRes.isInvalid())
hadError = true;
}
UpdateStructuredListElement(StructuredList, StructuredIndex,
ExprRes.takeAs<Expr>());
++Index;
return;
}
ExprRes.release();
// Fall through for subaggregate initialization
}
@ -2104,6 +2112,7 @@ bool InitializationSequence::isAmbiguous() const {
case FK_ReferenceInitDropsQualifiers:
case FK_ReferenceInitFailed:
case FK_ConversionFailed:
case FK_ConversionFromPropertyFailed:
case FK_TooManyInitsForScalar:
case FK_ReferenceBindingToInitList:
case FK_InitListBadDestinationType:
@ -3129,8 +3138,14 @@ InitializationSequence::InitializationSequence(Sema &S,
}
for (unsigned I = 0; I != NumArgs; ++I)
if (Args[I]->getObjectKind() == OK_ObjCProperty)
S.ConvertPropertyForRValue(Args[I]);
if (Args[I]->getObjectKind() == OK_ObjCProperty) {
ExprResult Result = S.ConvertPropertyForRValue(Args[I]);
if (Result.isInvalid()) {
SetFailed(FK_ConversionFromPropertyFailed);
return;
}
Args[I] = Result.take();
}
QualType SourceType;
Expr *Initializer = 0;
@ -3693,14 +3708,15 @@ InitializationSequence::Perform(Sema &S,
case SK_ObjCObjectConversion:
case SK_ArrayInit: {
assert(Args.size() == 1);
Expr *CurInitExpr = Args.get()[0];
if (!CurInitExpr) return ExprError();
CurInit = Args.get()[0];
if (!CurInit.get()) return ExprError();
// Read from a property when initializing something with it.
if (CurInitExpr->getObjectKind() == OK_ObjCProperty)
S.ConvertPropertyForRValue(CurInitExpr);
CurInit = ExprResult(CurInitExpr);
if (CurInit.get()->getObjectKind() == OK_ObjCProperty) {
CurInit = S.ConvertPropertyForRValue(CurInit.take());
if (CurInit.isInvalid())
return ExprError();
}
break;
}
@ -3717,14 +3733,13 @@ InitializationSequence::Perform(Sema &S,
if (CurInit.isInvalid())
return ExprError();
Expr *CurInitExpr = CurInit.get();
QualType SourceType = CurInitExpr? CurInitExpr->getType() : QualType();
QualType SourceType = CurInit.get() ? CurInit.get()->getType() : QualType();
switch (Step->Kind) {
case SK_ResolveAddressOfOverloadedFunction:
// Overload resolution determined which function invoke; update the
// initializer to reflect that choice.
S.CheckAddressOfMemberAccess(CurInitExpr, Step->Function.FoundDecl);
S.CheckAddressOfMemberAccess(CurInit.get(), Step->Function.FoundDecl);
S.DiagnoseUseOfDecl(Step->Function.FoundDecl, Kind.getLocation());
CurInit = S.FixOverloadedFunctionReference(move(CurInit),
Step->Function.FoundDecl,
@ -3742,8 +3757,8 @@ InitializationSequence::Perform(Sema &S,
// Casts to inaccessible base classes are allowed with C-style casts.
bool IgnoreBaseAccess = Kind.isCStyleOrFunctionalCast();
if (S.CheckDerivedToBaseConversion(SourceType, Step->Type,
CurInitExpr->getLocStart(),
CurInitExpr->getSourceRange(),
CurInit.get()->getLocStart(),
CurInit.get()->getSourceRange(),
&BasePath, IgnoreBaseAccess))
return ExprError();
@ -3752,7 +3767,7 @@ InitializationSequence::Perform(Sema &S,
if (const PointerType *Pointer = T->getAs<PointerType>())
T = Pointer->getPointeeType();
if (const RecordType *RecordTy = T->getAs<RecordType>())
S.MarkVTableUsed(CurInitExpr->getLocStart(),
S.MarkVTableUsed(CurInit.get()->getLocStart(),
cast<CXXRecordDecl>(RecordTy->getDecl()));
}
@ -3771,21 +3786,21 @@ InitializationSequence::Perform(Sema &S,
}
case SK_BindReference:
if (FieldDecl *BitField = CurInitExpr->getBitField()) {
if (FieldDecl *BitField = CurInit.get()->getBitField()) {
// References cannot bind to bit fields (C++ [dcl.init.ref]p5).
S.Diag(Kind.getLocation(), diag::err_reference_bind_to_bitfield)
<< Entity.getType().isVolatileQualified()
<< BitField->getDeclName()
<< CurInitExpr->getSourceRange();
<< CurInit.get()->getSourceRange();
S.Diag(BitField->getLocation(), diag::note_bitfield_decl);
return ExprError();
}
if (CurInitExpr->refersToVectorElement()) {
if (CurInit.get()->refersToVectorElement()) {
// References cannot bind to vector elements.
S.Diag(Kind.getLocation(), diag::err_reference_bind_to_vector_element)
<< Entity.getType().isVolatileQualified()
<< CurInitExpr->getSourceRange();
<< CurInit.get()->getSourceRange();
PrintInitLocationNote(S, Entity);
return ExprError();
}
@ -3793,7 +3808,7 @@ InitializationSequence::Perform(Sema &S,
// Reference binding does not have any corresponding ASTs.
// Check exception specifications
if (S.CheckExceptionSpecCompatibility(CurInitExpr, DestType))
if (S.CheckExceptionSpecCompatibility(CurInit.get(), DestType))
return ExprError();
break;
@ -3802,7 +3817,7 @@ InitializationSequence::Perform(Sema &S,
// Reference binding does not have any corresponding ASTs.
// Check exception specifications
if (S.CheckExceptionSpecCompatibility(CurInitExpr, DestType))
if (S.CheckExceptionSpecCompatibility(CurInit.get(), DestType))
return ExprError();
break;
@ -3824,13 +3839,14 @@ InitializationSequence::Perform(Sema &S,
if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(Fn)) {
// Build a call to the selected constructor.
ASTOwningVector<Expr*> ConstructorArgs(S);
SourceLocation Loc = CurInitExpr->getLocStart();
SourceLocation Loc = CurInit.get()->getLocStart();
CurInit.release(); // Ownership transferred into MultiExprArg, below.
// Determine the arguments required to actually perform the constructor
// call.
Expr *Arg = CurInit.get();
if (S.CompleteConstructorCall(Constructor,
MultiExprArg(&CurInitExpr, 1),
MultiExprArg(&Arg, 1),
Loc, ConstructorArgs))
return ExprError();
@ -3858,23 +3874,22 @@ InitializationSequence::Perform(Sema &S,
// Build a call to the conversion function.
CXXConversionDecl *Conversion = cast<CXXConversionDecl>(Fn);
IsLvalue = Conversion->getResultType()->isLValueReferenceType();
S.CheckMemberOperatorAccess(Kind.getLocation(), CurInitExpr, 0,
S.CheckMemberOperatorAccess(Kind.getLocation(), CurInit.get(), 0,
FoundFn);
S.DiagnoseUseOfDecl(FoundFn, Kind.getLocation());
// FIXME: Should we move this initialization into a separate
// derived-to-base conversion? I believe the answer is "no", because
// we don't want to turn off access control here for c-style casts.
if (S.PerformObjectArgumentInitialization(CurInitExpr, /*Qualifier=*/0,
FoundFn, Conversion))
ExprResult CurInitExprRes =
S.PerformObjectArgumentInitialization(CurInit.take(), /*Qualifier=*/0,
FoundFn, Conversion);
if(CurInitExprRes.isInvalid())
return ExprError();
// Do a little dance to make sure that CurInit has the proper
// pointer.
CurInit.release();
CurInit = move(CurInitExprRes);
// Build the actual call to the conversion function.
CurInit = S.BuildCXXMemberCallExpr(CurInitExpr, FoundFn, Conversion);
CurInit = S.BuildCXXMemberCallExpr(CurInit.get(), FoundFn, Conversion);
if (CurInit.isInvalid() || !CurInit.get())
return ExprError();
@ -3888,23 +3903,21 @@ InitializationSequence::Perform(Sema &S,
if (RequiresCopy || shouldBindAsTemporary(Entity))
CurInit = S.MaybeBindToTemporary(CurInit.takeAs<Expr>());
else if (CreatedObject && shouldDestroyTemporary(Entity)) {
CurInitExpr = static_cast<Expr *>(CurInit.get());
QualType T = CurInitExpr->getType();
QualType T = CurInit.get()->getType();
if (const RecordType *Record = T->getAs<RecordType>()) {
CXXDestructorDecl *Destructor
= S.LookupDestructor(cast<CXXRecordDecl>(Record->getDecl()));
S.CheckDestructorAccess(CurInitExpr->getLocStart(), Destructor,
S.CheckDestructorAccess(CurInit.get()->getLocStart(), Destructor,
S.PDiag(diag::err_access_dtor_temp) << T);
S.MarkDeclarationReferenced(CurInitExpr->getLocStart(), Destructor);
S.DiagnoseUseOfDecl(Destructor, CurInitExpr->getLocStart());
S.MarkDeclarationReferenced(CurInit.get()->getLocStart(), Destructor);
S.DiagnoseUseOfDecl(Destructor, CurInit.get()->getLocStart());
}
}
CurInitExpr = CurInit.takeAs<Expr>();
// FIXME: xvalues
CurInit = S.Owned(ImplicitCastExpr::Create(S.Context,
CurInitExpr->getType(),
CastKind, CurInitExpr, 0,
CurInit.get()->getType(),
CastKind, CurInit.get(), 0,
IsLvalue ? VK_LValue : VK_RValue));
if (RequiresCopy)
@ -3924,25 +3937,23 @@ InitializationSequence::Perform(Sema &S,
(Step->Kind == SK_QualificationConversionXValue ?
VK_XValue :
VK_RValue);
S.ImpCastExprToType(CurInitExpr, Step->Type, CK_NoOp, VK);
CurInit.release();
CurInit = S.Owned(CurInitExpr);
CurInit = S.ImpCastExprToType(CurInit.take(), Step->Type, CK_NoOp, VK);
break;
}
case SK_ConversionSequence: {
if (S.PerformImplicitConversion(CurInitExpr, Step->Type, *Step->ICS,
getAssignmentAction(Entity),
Kind.isCStyleOrFunctionalCast()))
ExprResult CurInitExprRes =
S.PerformImplicitConversion(CurInit.get(), Step->Type, *Step->ICS,
getAssignmentAction(Entity),
Kind.isCStyleOrFunctionalCast());
if (CurInitExprRes.isInvalid())
return ExprError();
CurInit.release();
CurInit = S.Owned(CurInitExpr);
CurInit = move(CurInitExprRes);
break;
}
case SK_ListInitialization: {
InitListExpr *InitList = cast<InitListExpr>(CurInitExpr);
InitListExpr *InitList = cast<InitListExpr>(CurInit.get());
QualType Ty = Step->Type;
if (S.CheckInitList(Entity, InitList, ResultType? *ResultType : Ty))
return ExprError();
@ -4075,54 +4086,57 @@ InitializationSequence::Perform(Sema &S,
}
case SK_CAssignment: {
QualType SourceType = CurInitExpr->getType();
QualType SourceType = CurInit.get()->getType();
ExprResult Result = move(CurInit);
Sema::AssignConvertType ConvTy =
S.CheckSingleAssignmentConstraints(Step->Type, CurInitExpr);
S.CheckSingleAssignmentConstraints(Step->Type, Result);
if (Result.isInvalid())
return ExprError();
CurInit = move(Result);
// If this is a call, allow conversion to a transparent union.
ExprResult CurInitExprRes = move(CurInit);
if (ConvTy != Sema::Compatible &&
Entity.getKind() == InitializedEntity::EK_Parameter &&
S.CheckTransparentUnionArgumentConstraints(Step->Type, CurInitExpr)
S.CheckTransparentUnionArgumentConstraints(Step->Type, CurInitExprRes)
== Sema::Compatible)
ConvTy = Sema::Compatible;
if (CurInitExprRes.isInvalid())
return ExprError();
CurInit = move(CurInitExprRes);
bool Complained;
if (S.DiagnoseAssignmentResult(ConvTy, Kind.getLocation(),
Step->Type, SourceType,
CurInitExpr,
CurInit.get(),
getAssignmentAction(Entity),
&Complained)) {
PrintInitLocationNote(S, Entity);
return ExprError();
} else if (Complained)
PrintInitLocationNote(S, Entity);
CurInit.release();
CurInit = S.Owned(CurInitExpr);
break;
}
case SK_StringInit: {
QualType Ty = Step->Type;
CheckStringInit(CurInitExpr, ResultType ? *ResultType : Ty,
CheckStringInit(CurInit.get(), ResultType ? *ResultType : Ty,
S.Context.getAsArrayType(Ty), S);
break;
}
case SK_ObjCObjectConversion:
S.ImpCastExprToType(CurInitExpr, Step->Type,
CurInit = S.ImpCastExprToType(CurInit.take(), Step->Type,
CK_ObjCObjectLValueCast,
S.CastCategory(CurInitExpr));
CurInit.release();
CurInit = S.Owned(CurInitExpr);
S.CastCategory(CurInit.get()));
break;
case SK_ArrayInit:
// Okay: we checked everything before creating this step. Note that
// this is a GNU extension.
S.Diag(Kind.getLocation(), diag::ext_array_init_copy)
<< Step->Type << CurInitExpr->getType()
<< CurInitExpr->getSourceRange();
<< Step->Type << CurInit.get()->getType()
<< CurInit.get()->getSourceRange();
// If the destination type is an incomplete array type, update the
// type accordingly.
@ -4130,7 +4144,7 @@ InitializationSequence::Perform(Sema &S,
if (const IncompleteArrayType *IncompleteDest
= S.Context.getAsIncompleteArrayType(Step->Type)) {
if (const ConstantArrayType *ConstantSource
= S.Context.getAsConstantArrayType(CurInitExpr->getType())) {
= S.Context.getAsConstantArrayType(CurInit.get()->getType())) {
*ResultType = S.Context.getConstantArrayType(
IncompleteDest->getElementType(),
ConstantSource->getSize(),
@ -4290,6 +4304,11 @@ bool InitializationSequence::Diagnose(Sema &S,
<< Args[0]->getSourceRange();
break;
}
case FK_ConversionFromPropertyFailed:
// No-op. This error has already been reported.
break;
case FK_TooManyInitsForScalar: {
SourceRange R;
@ -4489,6 +4508,10 @@ void InitializationSequence::dump(llvm::raw_ostream &OS) const {
OS << "conversion failed";
break;
case FK_ConversionFromPropertyFailed:
OS << "conversion from property failed";
break;
case FK_TooManyInitsForScalar:
OS << "too many initializers for scalar";
break;

View File

@ -36,12 +36,14 @@ using namespace sema;
/// A convenience routine for creating a decayed reference to a
/// function.
static Expr *
static ExprResult
CreateFunctionRefExpr(Sema &S, FunctionDecl *Fn,
SourceLocation Loc = SourceLocation()) {
Expr *E = new (S.Context) DeclRefExpr(Fn, Fn->getType(), VK_LValue, Loc);
S.DefaultFunctionArrayConversion(E);
return E;
ExprResult E = S.Owned(new (S.Context) DeclRefExpr(Fn, Fn->getType(), VK_LValue, Loc));
E = S.DefaultFunctionArrayConversion(E.take());
if (E.isInvalid())
return ExprError();
return move(E);
}
static bool IsStandardConversion(Sema &S, Expr* From, QualType ToType,
@ -886,20 +888,19 @@ bool Sema::TryImplicitConversion(InitializationSequence &Sequence,
}
/// PerformImplicitConversion - Perform an implicit conversion of the
/// expression From to the type ToType. Returns true if there was an
/// error, false otherwise. The expression From is replaced with the
/// expression From to the type ToType. Returns the
/// converted expression. Flavor is the kind of conversion we're
/// performing, used in the error message. If @p AllowExplicit,
/// explicit user-defined conversions are permitted.
bool
Sema::PerformImplicitConversion(Expr *&From, QualType ToType,
ExprResult
Sema::PerformImplicitConversion(Expr *From, QualType ToType,
AssignmentAction Action, bool AllowExplicit) {
ImplicitConversionSequence ICS;
return PerformImplicitConversion(From, ToType, Action, AllowExplicit, ICS);
}
bool
Sema::PerformImplicitConversion(Expr *&From, QualType ToType,
ExprResult
Sema::PerformImplicitConversion(Expr *From, QualType ToType,
AssignmentAction Action, bool AllowExplicit,
ImplicitConversionSequence& ICS) {
ICS = clang::TryImplicitConversion(*this, From, ToType,
@ -3525,8 +3526,8 @@ TryObjectArgumentInitialization(Sema &S, QualType OrigFromType,
/// PerformObjectArgumentInitialization - Perform initialization of
/// the implicit object parameter for the given Method with the given
/// expression.
bool
Sema::PerformObjectArgumentInitialization(Expr *&From,
ExprResult
Sema::PerformObjectArgumentInitialization(Expr *From,
NestedNameSpecifier *Qualifier,
NamedDecl *FoundDecl,
CXXMethodDecl *Method) {
@ -3562,7 +3563,7 @@ Sema::PerformObjectArgumentInitialization(Expr *&From,
<< From->getSourceRange();
Diag(Method->getLocation(), diag::note_previous_decl)
<< Method->getDeclName();
return true;
return ExprError();
}
}
@ -3571,13 +3572,18 @@ Sema::PerformObjectArgumentInitialization(Expr *&From,
<< ImplicitParamRecordType << FromRecordType << From->getSourceRange();
}
if (ICS.Standard.Second == ICK_Derived_To_Base)
return PerformObjectMemberConversion(From, Qualifier, FoundDecl, Method);
if (ICS.Standard.Second == ICK_Derived_To_Base) {
ExprResult FromRes =
PerformObjectMemberConversion(From, Qualifier, FoundDecl, Method);
if (FromRes.isInvalid())
return ExprError();
From = FromRes.take();
}
if (!Context.hasSameType(From->getType(), DestType))
ImpCastExprToType(From, DestType, CK_NoOp,
From->getType()->isPointerType() ? VK_RValue : VK_LValue);
return false;
From = ImpCastExprToType(From, DestType, CK_NoOp,
From->getType()->isPointerType() ? VK_RValue : VK_LValue).take();
return Owned(From);
}
/// TryContextuallyConvertToBool - Attempt to contextually convert the
@ -3595,7 +3601,7 @@ TryContextuallyConvertToBool(Sema &S, Expr *From) {
/// PerformContextuallyConvertToBool - Perform a contextual conversion
/// of the expression From to bool (C++0x [conv]p3).
bool Sema::PerformContextuallyConvertToBool(Expr *&From) {
ExprResult Sema::PerformContextuallyConvertToBool(Expr *From) {
ImplicitConversionSequence ICS = TryContextuallyConvertToBool(*this, From);
if (!ICS.isBad())
return PerformImplicitConversion(From, Context.BoolTy, ICS, AA_Converting);
@ -3604,7 +3610,7 @@ bool Sema::PerformContextuallyConvertToBool(Expr *&From) {
return Diag(From->getSourceRange().getBegin(),
diag::err_typecheck_bool_condition)
<< From->getType() << From->getSourceRange();
return true;
return ExprError();
}
/// TryContextuallyConvertToObjCId - Attempt to contextually convert the
@ -3622,12 +3628,12 @@ TryContextuallyConvertToObjCId(Sema &S, Expr *From) {
/// PerformContextuallyConvertToObjCId - Perform a contextual conversion
/// of the expression From to 'id'.
bool Sema::PerformContextuallyConvertToObjCId(Expr *&From) {
ExprResult Sema::PerformContextuallyConvertToObjCId(Expr *From) {
QualType Ty = Context.getObjCIdType();
ImplicitConversionSequence ICS = TryContextuallyConvertToObjCId(*this, From);
if (!ICS.isBad())
return PerformImplicitConversion(From, Ty, ICS, AA_Converting);
return true;
return ExprError();
}
/// \brief Attempt to convert the given expression to an integral or
@ -7565,19 +7571,20 @@ ExprResult Sema::ResolveAndFixSingleFunctionTemplateSpecialization(
assert(SrcExpr->getType() == Context.OverloadTy);
DeclAccessPair Found;
Expr* SingleFunctionExpression = 0;
ExprResult SingleFunctionExpression;
if (FunctionDecl* Fn = ResolveSingleFunctionTemplateSpecialization(
SrcExpr, false, // false -> Complain
&Found)) {
if (!DiagnoseUseOfDecl(Fn, SrcExpr->getSourceRange().getBegin())) {
// mark the expression as resolved to Fn
SingleFunctionExpression = FixOverloadedFunctionReference(SrcExpr,
Found, Fn);
SingleFunctionExpression = Owned(FixOverloadedFunctionReference(SrcExpr,
Found, Fn));
if (DoFunctionPointerConverion)
DefaultFunctionArrayLvalueConversion(SingleFunctionExpression);
SingleFunctionExpression =
DefaultFunctionArrayLvalueConversion(SingleFunctionExpression.take());
}
}
if (!SingleFunctionExpression) {
if (!SingleFunctionExpression.isUsable()) {
if (Complain) {
OverloadExpr* oe = OverloadExpr::find(SrcExpr).Expression;
Diag(OpRangeForComplaining.getBegin(), DiagIDForComplaining)
@ -7847,8 +7854,12 @@ Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, unsigned OpcIn,
// TODO: provide better source location info.
DeclarationNameInfo OpNameInfo(OpName, OpLoc);
if (Input->getObjectKind() == OK_ObjCProperty)
ConvertPropertyForRValue(Input);
if (Input->getObjectKind() == OK_ObjCProperty) {
ExprResult Result = ConvertPropertyForRValue(Input);
if (Result.isInvalid())
return ExprError();
Input = Result.take();
}
Expr *Args[2] = { Input, 0 };
unsigned NumArgs = 1;
@ -7919,9 +7930,12 @@ Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, unsigned OpcIn,
if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(FnDecl)) {
CheckMemberOperatorAccess(OpLoc, Args[0], 0, Best->FoundDecl);
if (PerformObjectArgumentInitialization(Input, /*Qualifier=*/0,
Best->FoundDecl, Method))
ExprResult InputRes =
PerformObjectArgumentInitialization(Input, /*Qualifier=*/0,
Best->FoundDecl, Method);
if (InputRes.isInvalid())
return ExprError();
Input = InputRes.take();
} else {
// Convert the arguments.
ExprResult InputInit
@ -7943,11 +7957,13 @@ Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, unsigned OpcIn,
ResultTy = ResultTy.getNonLValueExprType(Context);
// Build the actual expression node.
Expr *FnExpr = CreateFunctionRefExpr(*this, FnDecl);
ExprResult FnExpr = CreateFunctionRefExpr(*this, FnDecl);
if (FnExpr.isInvalid())
return ExprError();
Args[0] = Input;
CallExpr *TheCall =
new (Context) CXXOperatorCallExpr(Context, Op, FnExpr,
new (Context) CXXOperatorCallExpr(Context, Op, FnExpr.take(),
Args, NumArgs, ResultTy, VK, OpLoc);
if (CheckCallReturnType(FnDecl->getResultType(), OpLoc, TheCall,
@ -7959,38 +7975,40 @@ Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, unsigned OpcIn,
// We matched a built-in operator. Convert the arguments, then
// break out so that we will build the appropriate built-in
// operator node.
if (PerformImplicitConversion(Input, Best->BuiltinTypes.ParamTypes[0],
Best->Conversions[0], AA_Passing))
return ExprError();
break;
}
}
case OR_No_Viable_Function:
// No viable function; fall through to handling this as a
// built-in operator, which will produce an error message for us.
ExprResult InputRes =
PerformImplicitConversion(Input, Best->BuiltinTypes.ParamTypes[0],
Best->Conversions[0], AA_Passing);
if (InputRes.isInvalid())
return ExprError();
Input = InputRes.take();
break;
case OR_Ambiguous:
Diag(OpLoc, diag::err_ovl_ambiguous_oper_unary)
<< UnaryOperator::getOpcodeStr(Opc)
<< Input->getType()
<< Input->getSourceRange();
CandidateSet.NoteCandidates(*this, OCD_ViableCandidates,
Args, NumArgs,
UnaryOperator::getOpcodeStr(Opc), OpLoc);
return ExprError();
case OR_Deleted:
Diag(OpLoc, diag::err_ovl_deleted_oper)
<< Best->Function->isDeleted()
<< UnaryOperator::getOpcodeStr(Opc)
<< getDeletedOrUnavailableSuffix(Best->Function)
<< Input->getSourceRange();
CandidateSet.NoteCandidates(*this, OCD_AllCandidates, Args, NumArgs);
return ExprError();
}
}
case OR_No_Viable_Function:
// No viable function; fall through to handling this as a
// built-in operator, which will produce an error message for us.
break;
case OR_Ambiguous:
Diag(OpLoc, diag::err_ovl_ambiguous_oper_unary)
<< UnaryOperator::getOpcodeStr(Opc)
<< Input->getType()
<< Input->getSourceRange();
CandidateSet.NoteCandidates(*this, OCD_ViableCandidates,
Args, NumArgs,
UnaryOperator::getOpcodeStr(Opc), OpLoc);
return ExprError();
case OR_Deleted:
Diag(OpLoc, diag::err_ovl_deleted_oper)
<< Best->Function->isDeleted()
<< UnaryOperator::getOpcodeStr(Opc)
<< getDeletedOrUnavailableSuffix(Best->Function)
<< Input->getSourceRange();
CandidateSet.NoteCandidates(*this, OCD_AllCandidates, Args, NumArgs);
return ExprError();
}
// Either we found no viable overloaded operator or we matched a
// built-in operator. In either case, fall through to trying to
@ -8065,8 +8083,12 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc,
}
// Always do property rvalue conversions on the RHS.
if (Args[1]->getObjectKind() == OK_ObjCProperty)
ConvertPropertyForRValue(Args[1]);
if (Args[1]->getObjectKind() == OK_ObjCProperty) {
ExprResult Result = ConvertPropertyForRValue(Args[1]);
if (Result.isInvalid())
return ExprError();
Args[1] = Result.take();
}
// The LHS is more complicated.
if (Args[0]->getObjectKind() == OK_ObjCProperty) {
@ -8094,7 +8116,10 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc,
return CreateBuiltinBinOp(OpLoc, Opc, Args[0], Args[1]);
}
ConvertPropertyForRValue(Args[0]);
ExprResult Result = ConvertPropertyForRValue(Args[0]);
if (Result.isInvalid())
return ExprError();
Args[0] = Result.take();
}
// If this is the assignment operator, we only perform overload resolution
@ -8155,10 +8180,12 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc,
if (Arg1.isInvalid())
return ExprError();
if (PerformObjectArgumentInitialization(Args[0], /*Qualifier=*/0,
Best->FoundDecl, Method))
ExprResult Arg0 =
PerformObjectArgumentInitialization(Args[0], /*Qualifier=*/0,
Best->FoundDecl, Method);
if (Arg0.isInvalid())
return ExprError();
Args[0] = Arg0.takeAs<Expr>();
Args[1] = RHS = Arg1.takeAs<Expr>();
} else {
// Convert the arguments.
@ -8188,10 +8215,12 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc,
ResultTy = ResultTy.getNonLValueExprType(Context);
// Build the actual expression node.
Expr *FnExpr = CreateFunctionRefExpr(*this, FnDecl, OpLoc);
ExprResult FnExpr = CreateFunctionRefExpr(*this, FnDecl, OpLoc);
if (FnExpr.isInvalid())
return ExprError();
CXXOperatorCallExpr *TheCall =
new (Context) CXXOperatorCallExpr(Context, Op, FnExpr,
new (Context) CXXOperatorCallExpr(Context, Op, FnExpr.take(),
Args, 2, ResultTy, VK, OpLoc);
if (CheckCallReturnType(FnDecl->getResultType(), OpLoc, TheCall,
@ -8203,12 +8232,19 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc,
// We matched a built-in operator. Convert the arguments, then
// break out so that we will build the appropriate built-in
// operator node.
if (PerformImplicitConversion(Args[0], Best->BuiltinTypes.ParamTypes[0],
Best->Conversions[0], AA_Passing) ||
PerformImplicitConversion(Args[1], Best->BuiltinTypes.ParamTypes[1],
Best->Conversions[1], AA_Passing))
ExprResult ArgsRes0 =
PerformImplicitConversion(Args[0], Best->BuiltinTypes.ParamTypes[0],
Best->Conversions[0], AA_Passing);
if (ArgsRes0.isInvalid())
return ExprError();
Args[0] = ArgsRes0.take();
ExprResult ArgsRes1 =
PerformImplicitConversion(Args[1], Best->BuiltinTypes.ParamTypes[1],
Best->Conversions[1], AA_Passing);
if (ArgsRes1.isInvalid())
return ExprError();
Args[1] = ArgsRes1.take();
break;
}
}
@ -8297,10 +8333,18 @@ Sema::CreateOverloadedArraySubscriptExpr(SourceLocation LLoc,
RLoc));
}
if (Args[0]->getObjectKind() == OK_ObjCProperty)
ConvertPropertyForRValue(Args[0]);
if (Args[1]->getObjectKind() == OK_ObjCProperty)
ConvertPropertyForRValue(Args[1]);
if (Args[0]->getObjectKind() == OK_ObjCProperty) {
ExprResult Result = ConvertPropertyForRValue(Args[0]);
if (Result.isInvalid())
return ExprError();
Args[0] = Result.take();
}
if (Args[1]->getObjectKind() == OK_ObjCProperty) {
ExprResult Result = ConvertPropertyForRValue(Args[1]);
if (Result.isInvalid())
return ExprError();
Args[1] = Result.take();
}
// Build an empty overload set.
OverloadCandidateSet CandidateSet(LLoc);
@ -8331,9 +8375,12 @@ Sema::CreateOverloadedArraySubscriptExpr(SourceLocation LLoc,
// Convert the arguments.
CXXMethodDecl *Method = cast<CXXMethodDecl>(FnDecl);
if (PerformObjectArgumentInitialization(Args[0], /*Qualifier=*/0,
Best->FoundDecl, Method))
ExprResult Arg0 =
PerformObjectArgumentInitialization(Args[0], /*Qualifier=*/0,
Best->FoundDecl, Method);
if (Arg0.isInvalid())
return ExprError();
Args[0] = Arg0.take();
// Convert the arguments.
ExprResult InputInit
@ -8353,11 +8400,13 @@ Sema::CreateOverloadedArraySubscriptExpr(SourceLocation LLoc,
ResultTy = ResultTy.getNonLValueExprType(Context);
// Build the actual expression node.
Expr *FnExpr = CreateFunctionRefExpr(*this, FnDecl, LLoc);
ExprResult FnExpr = CreateFunctionRefExpr(*this, FnDecl, LLoc);
if (FnExpr.isInvalid())
return ExprError();
CXXOperatorCallExpr *TheCall =
new (Context) CXXOperatorCallExpr(Context, OO_Subscript,
FnExpr, Args, 2,
FnExpr.take(), Args, 2,
ResultTy, VK, RLoc);
if (CheckCallReturnType(FnDecl->getResultType(), LLoc, TheCall,
@ -8369,11 +8418,19 @@ Sema::CreateOverloadedArraySubscriptExpr(SourceLocation LLoc,
// We matched a built-in operator. Convert the arguments, then
// break out so that we will build the appropriate built-in
// operator node.
if (PerformImplicitConversion(Args[0], Best->BuiltinTypes.ParamTypes[0],
Best->Conversions[0], AA_Passing) ||
PerformImplicitConversion(Args[1], Best->BuiltinTypes.ParamTypes[1],
Best->Conversions[1], AA_Passing))
ExprResult ArgsRes0 =
PerformImplicitConversion(Args[0], Best->BuiltinTypes.ParamTypes[0],
Best->Conversions[0], AA_Passing);
if (ArgsRes0.isInvalid())
return ExprError();
Args[0] = ArgsRes0.take();
ExprResult ArgsRes1 =
PerformImplicitConversion(Args[1], Best->BuiltinTypes.ParamTypes[1],
Best->Conversions[1], AA_Passing);
if (ArgsRes1.isInvalid())
return ExprError();
Args[1] = ArgsRes1.take();
break;
}
@ -8559,12 +8616,14 @@ Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE,
// Convert the object argument (for a non-static member function call).
// We only need to do this if there was actually an overload; otherwise
// it was done at lookup.
Expr *ObjectArg = MemExpr->getBase();
if (!Method->isStatic() &&
PerformObjectArgumentInitialization(ObjectArg, Qualifier,
FoundDecl, Method))
return ExprError();
MemExpr->setBase(ObjectArg);
if (!Method->isStatic()) {
ExprResult ObjectArg =
PerformObjectArgumentInitialization(MemExpr->getBase(), Qualifier,
FoundDecl, Method);
if (ObjectArg.isInvalid())
return ExprError();
MemExpr->setBase(ObjectArg.take());
}
// Convert the rest of the arguments
const FunctionProtoType *Proto =
@ -8584,15 +8643,19 @@ Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE,
/// overloaded function call operator (@c operator()) or performing a
/// user-defined conversion on the object argument.
ExprResult
Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Object,
Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Obj,
SourceLocation LParenLoc,
Expr **Args, unsigned NumArgs,
SourceLocation RParenLoc) {
if (Object->getObjectKind() == OK_ObjCProperty)
ConvertPropertyForRValue(Object);
ExprResult Object = Owned(Obj);
if (Object.get()->getObjectKind() == OK_ObjCProperty) {
Object = ConvertPropertyForRValue(Object.take());
if (Object.isInvalid())
return ExprError();
}
assert(Object->getType()->isRecordType() && "Requires object type argument");
const RecordType *Record = Object->getType()->getAs<RecordType>();
assert(Object.get()->getType()->isRecordType() && "Requires object type argument");
const RecordType *Record = Object.get()->getType()->getAs<RecordType>();
// C++ [over.call.object]p1:
// If the primary-expression E in the function call syntax
@ -8604,9 +8667,9 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Object,
OverloadCandidateSet CandidateSet(LParenLoc);
DeclarationName OpName = Context.DeclarationNames.getCXXOperatorName(OO_Call);
if (RequireCompleteType(LParenLoc, Object->getType(),
if (RequireCompleteType(LParenLoc, Object.get()->getType(),
PDiag(diag::err_incomplete_object_call)
<< Object->getSourceRange()))
<< Object.get()->getSourceRange()))
return true;
LookupResult R(*this, OpName, LParenLoc, LookupOrdinaryName);
@ -8615,8 +8678,8 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Object,
for (LookupResult::iterator Oper = R.begin(), OperEnd = R.end();
Oper != OperEnd; ++Oper) {
AddMethodCandidate(Oper.getPair(), Object->getType(),
Object->Classify(Context), Args, NumArgs, CandidateSet,
AddMethodCandidate(Oper.getPair(), Object.get()->getType(),
Object.get()->Classify(Context), Args, NumArgs, CandidateSet,
/*SuppressUserConversions=*/ false);
}
@ -8661,12 +8724,12 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Object,
if (const FunctionProtoType *Proto = ConvType->getAs<FunctionProtoType>())
AddSurrogateCandidate(Conv, I.getPair(), ActingContext, Proto,
Object, Args, NumArgs, CandidateSet);
Object.get(), Args, NumArgs, CandidateSet);
}
// Perform overload resolution.
OverloadCandidateSet::iterator Best;
switch (CandidateSet.BestViableFunction(*this, Object->getLocStart(),
switch (CandidateSet.BestViableFunction(*this, Object.get()->getLocStart(),
Best)) {
case OR_Success:
// Overload resolution succeeded; we'll build the appropriate call
@ -8675,30 +8738,30 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Object,
case OR_No_Viable_Function:
if (CandidateSet.empty())
Diag(Object->getSourceRange().getBegin(), diag::err_ovl_no_oper)
<< Object->getType() << /*call*/ 1
<< Object->getSourceRange();
Diag(Object.get()->getSourceRange().getBegin(), diag::err_ovl_no_oper)
<< Object.get()->getType() << /*call*/ 1
<< Object.get()->getSourceRange();
else
Diag(Object->getSourceRange().getBegin(),
Diag(Object.get()->getSourceRange().getBegin(),
diag::err_ovl_no_viable_object_call)
<< Object->getType() << Object->getSourceRange();
<< Object.get()->getType() << Object.get()->getSourceRange();
CandidateSet.NoteCandidates(*this, OCD_AllCandidates, Args, NumArgs);
break;
case OR_Ambiguous:
Diag(Object->getSourceRange().getBegin(),
Diag(Object.get()->getSourceRange().getBegin(),
diag::err_ovl_ambiguous_object_call)
<< Object->getType() << Object->getSourceRange();
<< Object.get()->getType() << Object.get()->getSourceRange();
CandidateSet.NoteCandidates(*this, OCD_ViableCandidates, Args, NumArgs);
break;
case OR_Deleted:
Diag(Object->getSourceRange().getBegin(),
Diag(Object.get()->getSourceRange().getBegin(),
diag::err_ovl_deleted_object_call)
<< Best->Function->isDeleted()
<< Object->getType()
<< Object.get()->getType()
<< getDeletedOrUnavailableSuffix(Best->Function)
<< Object->getSourceRange();
<< Object.get()->getSourceRange();
CandidateSet.NoteCandidates(*this, OCD_AllCandidates, Args, NumArgs);
break;
}
@ -8713,7 +8776,7 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Object,
= cast<CXXConversionDecl>(
Best->Conversions[0].UserDefined.ConversionFunction);
CheckMemberOperatorAccess(LParenLoc, Object, 0, Best->FoundDecl);
CheckMemberOperatorAccess(LParenLoc, Object.get(), 0, Best->FoundDecl);
DiagnoseUseOfDecl(Best->FoundDecl, LParenLoc);
// We selected one of the surrogate functions that converts the
@ -8722,7 +8785,7 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Object,
// Create an implicit member expr to refer to the conversion operator.
// and then call it.
ExprResult Call = BuildCXXMemberCallExpr(Object, Best->FoundDecl, Conv);
ExprResult Call = BuildCXXMemberCallExpr(Object.get(), Best->FoundDecl, Conv);
if (Call.isInvalid())
return ExprError();
@ -8731,7 +8794,7 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Object,
}
MarkDeclarationReferenced(LParenLoc, Best->Function);
CheckMemberOperatorAccess(LParenLoc, Object, 0, Best->FoundDecl);
CheckMemberOperatorAccess(LParenLoc, Object.get(), 0, Best->FoundDecl);
DiagnoseUseOfDecl(Best->FoundDecl, LParenLoc);
// We found an overloaded operator(). Build a CXXOperatorCallExpr
@ -8754,11 +8817,13 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Object,
} else {
MethodArgs = new Expr*[NumArgs + 1];
}
MethodArgs[0] = Object;
MethodArgs[0] = Object.get();
for (unsigned ArgIdx = 0; ArgIdx < NumArgs; ++ArgIdx)
MethodArgs[ArgIdx + 1] = Args[ArgIdx];
Expr *NewFn = CreateFunctionRefExpr(*this, Method);
ExprResult NewFn = CreateFunctionRefExpr(*this, Method);
if (NewFn.isInvalid())
return true;
// Once we've built TheCall, all of the expressions are properly
// owned.
@ -8767,7 +8832,7 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Object,
ResultTy = ResultTy.getNonLValueExprType(Context);
CXXOperatorCallExpr *TheCall =
new (Context) CXXOperatorCallExpr(Context, OO_Call, NewFn,
new (Context) CXXOperatorCallExpr(Context, OO_Call, NewFn.take(),
MethodArgs, NumArgs + 1,
ResultTy, VK, RParenLoc);
delete [] MethodArgs;
@ -8786,10 +8851,14 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Object,
bool IsError = false;
// Initialize the implicit object parameter.
IsError |= PerformObjectArgumentInitialization(Object, /*Qualifier=*/0,
Best->FoundDecl, Method);
TheCall->setArg(0, Object);
ExprResult ObjRes =
PerformObjectArgumentInitialization(Object.get(), /*Qualifier=*/0,
Best->FoundDecl, Method);
if (ObjRes.isInvalid())
IsError = true;
else
Object = move(ObjRes);
TheCall->setArg(0, Object.take());
// Check the argument types.
for (unsigned i = 0; i != NumArgsToCheck; i++) {
@ -8825,9 +8894,9 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Object,
if (Proto->isVariadic()) {
// Promote the arguments (C99 6.5.2.2p7).
for (unsigned i = NumArgsInProto; i != NumArgs; i++) {
Expr *Arg = Args[i];
IsError |= DefaultVariadicArgumentPromotion(Arg, VariadicMethod, 0);
TheCall->setArg(i + 1, Arg);
ExprResult Arg = DefaultVariadicArgumentPromotion(Args[i], VariadicMethod, 0);
IsError |= Arg.isInvalid();
TheCall->setArg(i + 1, Arg.take());
}
}
@ -8847,8 +8916,12 @@ Sema::BuildOverloadedArrowExpr(Scope *S, Expr *Base, SourceLocation OpLoc) {
assert(Base->getType()->isRecordType() &&
"left-hand side must have class type");
if (Base->getObjectKind() == OK_ObjCProperty)
ConvertPropertyForRValue(Base);
if (Base->getObjectKind() == OK_ObjCProperty) {
ExprResult Result = ConvertPropertyForRValue(Base);
if (Result.isInvalid())
return ExprError();
Base = Result.take();
}
SourceLocation Loc = Base->getExprLoc();
@ -8917,18 +8990,23 @@ Sema::BuildOverloadedArrowExpr(Scope *S, Expr *Base, SourceLocation OpLoc) {
// Convert the object parameter.
CXXMethodDecl *Method = cast<CXXMethodDecl>(Best->Function);
if (PerformObjectArgumentInitialization(Base, /*Qualifier=*/0,
Best->FoundDecl, Method))
ExprResult BaseResult =
PerformObjectArgumentInitialization(Base, /*Qualifier=*/0,
Best->FoundDecl, Method);
if (BaseResult.isInvalid())
return ExprError();
Base = BaseResult.take();
// Build the operator call.
Expr *FnExpr = CreateFunctionRefExpr(*this, Method);
ExprResult FnExpr = CreateFunctionRefExpr(*this, Method);
if (FnExpr.isInvalid())
return ExprError();
QualType ResultTy = Method->getResultType();
ExprValueKind VK = Expr::getValueKindForType(ResultTy);
ResultTy = ResultTy.getNonLValueExprType(Context);
CXXOperatorCallExpr *TheCall =
new (Context) CXXOperatorCallExpr(Context, OO_Arrow, FnExpr,
new (Context) CXXOperatorCallExpr(Context, OO_Arrow, FnExpr.take(),
&Base, 1, ResultTy, VK, OpLoc);
if (CheckCallReturnType(Method->getResultType(), OpLoc, TheCall,

View File

@ -469,7 +469,10 @@ Sema::ActOnFinishSwitchStmt(SourceLocation SwitchLoc, Stmt *Switch,
GetTypeBeforeIntegralPromotion(CondExpr);
// C99 6.8.4.2p5 - Integer promotions are performed on the controlling expr.
UsualUnaryConversions(CondExpr);
ExprResult CondResult = UsualUnaryConversions(CondExpr);
if (CondResult.isInvalid())
return StmtError();
CondExpr = CondResult.take();
QualType CondType = CondExpr->getType();
SS->setCond(CondExpr);
@ -555,7 +558,7 @@ Sema::ActOnFinishSwitchStmt(SourceLocation SwitchLoc, Stmt *Switch,
// If the LHS is not the same type as the condition, insert an implicit
// cast.
ImpCastExprToType(Lo, CondType, CK_IntegralCast);
Lo = ImpCastExprToType(Lo, CondType, CK_IntegralCast).take();
CS->setLHS(Lo);
// If this is a case range, remember it in CaseRanges, otherwise CaseVals.
@ -634,7 +637,7 @@ Sema::ActOnFinishSwitchStmt(SourceLocation SwitchLoc, Stmt *Switch,
// If the LHS is not the same type as the condition, insert an implicit
// cast.
ImpCastExprToType(Hi, CondType, CK_IntegralCast);
Hi = ImpCastExprToType(Hi, CondType, CK_IntegralCast).take();
CR->setRHS(Hi);
// If the low value is bigger than the high value, the case is empty.
@ -868,11 +871,13 @@ Sema::ActOnDoStmt(SourceLocation DoLoc, Stmt *Body,
Expr *Cond, SourceLocation CondRParen) {
assert(Cond && "ActOnDoStmt(): missing expression");
if (CheckBooleanCondition(Cond, DoLoc))
ExprResult CondResult = CheckBooleanCondition(Cond, DoLoc);
if (CondResult.isInvalid() || CondResult.isInvalid())
return StmtError();
Cond = CondResult.take();
CheckImplicitConversions(Cond, DoLoc);
ExprResult CondResult = MaybeCreateExprWithCleanups(Cond);
CondResult = MaybeCreateExprWithCleanups(Cond);
if (CondResult.isInvalid())
return StmtError();
Cond = CondResult.take();
@ -973,7 +978,10 @@ Sema::ActOnObjCForCollectionStmt(SourceLocation ForLoc,
<< FirstType << First->getSourceRange();
}
if (Second && !Second->isTypeDependent()) {
DefaultFunctionArrayLvalueConversion(Second);
ExprResult Result = DefaultFunctionArrayLvalueConversion(Second);
if (Result.isInvalid())
return StmtError();
Second = Result.take();
QualType SecondType = Second->getType();
if (!SecondType->isObjCObjectPointerType())
Diag(ForLoc, diag::err_collection_expr_type)
@ -1020,8 +1028,12 @@ Sema::ActOnIndirectGotoStmt(SourceLocation GotoLoc, SourceLocation StarLoc,
if (!E->isTypeDependent()) {
QualType ETy = E->getType();
QualType DestTy = Context.getPointerType(Context.VoidTy.withConst());
ExprResult ExprRes = Owned(E);
AssignConvertType ConvTy =
CheckSingleAssignmentConstraints(DestTy, E);
CheckSingleAssignmentConstraints(DestTy, ExprRes);
if (ExprRes.isInvalid())
return StmtError();
E = ExprRes.take();
if (DiagnoseAssignmentResult(ConvTy, StarLoc, DestTy, ETy, E, AA_Passing))
return StmtError();
}
@ -1188,7 +1200,10 @@ Sema::ActOnBlockReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) {
if (RetValExp) {
// Don't call UsualUnaryConversions(), since we don't want to do
// integer promotions here.
DefaultFunctionArrayLvalueConversion(RetValExp);
ExprResult Result = DefaultFunctionArrayLvalueConversion(RetValExp);
if (Result.isInvalid())
return StmtError();
RetValExp = Result.take();
CurBlock->ReturnType = RetValExp->getType();
if (BlockDeclRefExpr *CDRE = dyn_cast<BlockDeclRefExpr>(RetValExp)) {
// We have to remove a 'const' added to copied-in variable which was
@ -1290,8 +1305,12 @@ Sema::ActOnReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) {
if (RetValExp->getType()->isVoidType())
D = diag::ext_return_has_void_expr;
else {
IgnoredValueConversions(RetValExp);
ImpCastExprToType(RetValExp, Context.VoidTy, CK_ToVoid);
ExprResult Result = Owned(RetValExp);
Result = IgnoredValueConversions(Result.take());
if (Result.isInvalid())
return StmtError();
RetValExp = Result.take();
RetValExp = ImpCastExprToType(RetValExp, Context.VoidTy, CK_ToVoid).take();
}
// return (some void expression); is legal in C++.
@ -1498,8 +1517,11 @@ StmtResult Sema::ActOnAsmStmt(SourceLocation AsmLoc, bool IsSimple,
}
}
DefaultFunctionArrayLvalueConversion(Exprs[i]);
ExprResult Result = DefaultFunctionArrayLvalueConversion(Exprs[i]);
if (Result.isInvalid())
return StmtError();
Exprs[i] = Result.take();
InputConstraintInfos.push_back(Info);
}
@ -1614,7 +1636,7 @@ StmtResult Sema::ActOnAsmStmt(SourceLocation AsmLoc, bool IsSimple,
if (InputDomain == AD_Int && OutputDomain == AD_Int &&
!isOperandMentioned(InputOpNo, Pieces) &&
InputExpr->isEvaluatable(Context)) {
ImpCastExprToType(InputExpr, OutTy, CK_IntegralCast);
InputExpr = ImpCastExprToType(InputExpr, OutTy, CK_IntegralCast).take();
Exprs[InputOpNo] = InputExpr;
NS->setInputExpr(i, InputExpr);
continue;
@ -1663,8 +1685,11 @@ Sema::ActOnObjCAtTryStmt(SourceLocation AtLoc, Stmt *Try,
StmtResult Sema::BuildObjCAtThrowStmt(SourceLocation AtLoc,
Expr *Throw) {
if (Throw) {
DefaultLvalueConversion(Throw);
ExprResult Result = DefaultLvalueConversion(Throw);
if (Result.isInvalid())
return StmtError();
Throw = Result.take();
QualType ThrowType = Throw->getType();
// Make sure the expression type is an ObjC pointer or "void *".
if (!ThrowType->isDependentType() &&
@ -1703,8 +1728,11 @@ Sema::ActOnObjCAtSynchronizedStmt(SourceLocation AtLoc, Expr *SyncExpr,
Stmt *SyncBody) {
getCurFunction()->setHasBranchProtectedScope();
DefaultLvalueConversion(SyncExpr);
ExprResult Result = DefaultLvalueConversion(SyncExpr);
if (Result.isInvalid())
return StmtError();
SyncExpr = Result.take();
// Make sure the expression type is an ObjC pointer or "void *".
if (!SyncExpr->getType()->isDependentType() &&
!SyncExpr->getType()->isObjCObjectPointerType()) {

View File

@ -680,10 +680,12 @@ Decl *Sema::ActOnNonTypeTemplateParameter(Scope *S, Declarator &D,
return Param;
TemplateArgument Converted;
if (CheckTemplateArgument(Param, Param->getType(), Default, Converted)) {
ExprResult DefaultRes = CheckTemplateArgument(Param, Param->getType(), Default, Converted);
if (DefaultRes.isInvalid()) {
Param->setInvalidDecl();
return Param;
}
Default = DefaultRes.take();
Param->setDefaultArgument(Default, false);
}
@ -2418,9 +2420,11 @@ bool Sema::CheckTemplateArgument(NamedDecl *Param,
return true;
case TemplateArgument::Expression: {
Expr *E = Arg.getArgument().getAsExpr();
TemplateArgument Result;
if (CheckTemplateArgument(NTTP, NTTPType, E, Result, CTAK))
ExprResult Res =
CheckTemplateArgument(NTTP, NTTPType, Arg.getArgument().getAsExpr(),
Result, CTAK);
if (Res.isInvalid())
return true;
Converted.push_back(Result);
@ -2451,23 +2455,21 @@ bool Sema::CheckTemplateArgument(NamedDecl *Param,
CXXScopeSpec SS;
SS.Adopt(Arg.getTemplateQualifierLoc());
Expr *E = DependentScopeDeclRefExpr::Create(Context,
ExprResult E = Owned(DependentScopeDeclRefExpr::Create(Context,
SS.getWithLocInContext(Context),
NameInfo);
NameInfo));
// If we parsed the template argument as a pack expansion, create a
// pack expansion expression.
if (Arg.getArgument().getKind() == TemplateArgument::TemplateExpansion){
ExprResult Expansion = ActOnPackExpansion(E,
Arg.getTemplateEllipsisLoc());
if (Expansion.isInvalid())
E = ActOnPackExpansion(E.take(), Arg.getTemplateEllipsisLoc());
if (E.isInvalid())
return true;
E = Expansion.get();
}
TemplateArgument Result;
if (CheckTemplateArgument(NTTP, NTTPType, E, Result))
E = CheckTemplateArgument(NTTP, NTTPType, E.take(), Result);
if (E.isInvalid())
return true;
Converted.push_back(Result);
@ -3389,15 +3391,14 @@ bool Sema::CheckTemplateArgumentPointerToMember(Expr *Arg,
/// non-type template parameter.
///
/// This routine implements the semantics of C++ [temp.arg.nontype].
/// It returns true if an error occurred, and false otherwise. \p
/// If an error occurred, it returns ExprError(); otherwise, it
/// returns the converted template argument. \p
/// InstantiatedParamType is the type of the non-type template
/// parameter after it has been instantiated.
///
/// If no error was detected, Converted receives the converted template argument.
bool Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
QualType InstantiatedParamType, Expr *&Arg,
TemplateArgument &Converted,
CheckTemplateArgumentKind CTAK) {
ExprResult Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
QualType InstantiatedParamType, Expr *Arg,
TemplateArgument &Converted,
CheckTemplateArgumentKind CTAK) {
SourceLocation StartLoc = Arg->getSourceRange().getBegin();
// If either the parameter has a dependent type or the argument is
@ -3405,7 +3406,7 @@ bool Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
if (InstantiatedParamType->isDependentType() || Arg->isTypeDependent()) {
// FIXME: Produce a cloned, canonical expression?
Converted = TemplateArgument(Arg);
return false;
return Owned(Arg);
}
// C++ [temp.arg.nontype]p5:
@ -3435,12 +3436,12 @@ bool Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
diag::err_template_arg_not_integral_or_enumeral)
<< ArgType << Arg->getSourceRange();
Diag(Param->getLocation(), diag::note_template_param_here);
return true;
return ExprError();
} else if (!Arg->isValueDependent() &&
!Arg->isIntegerConstantExpr(Value, Context, &NonConstantLoc)) {
Diag(NonConstantLoc, diag::err_template_arg_not_ice)
<< ArgType << Arg->getSourceRange();
return true;
return ExprError();
}
// From here on out, all we care about are the unqualified forms
@ -3463,21 +3464,21 @@ bool Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
Diag(StartLoc, diag::err_deduced_non_type_template_arg_type_mismatch)
<< ArgType << ParamType;
Diag(Param->getLocation(), diag::note_template_param_here);
return true;
return ExprError();
} else if (ParamType->isBooleanType()) {
// This is an integral-to-boolean conversion.
ImpCastExprToType(Arg, ParamType, CK_IntegralToBoolean);
Arg = ImpCastExprToType(Arg, ParamType, CK_IntegralToBoolean).take();
} else if (IsIntegralPromotion(Arg, ArgType, ParamType) ||
!ParamType->isEnumeralType()) {
// This is an integral promotion or conversion.
ImpCastExprToType(Arg, ParamType, CK_IntegralCast);
Arg = ImpCastExprToType(Arg, ParamType, CK_IntegralCast).take();
} else {
// We can't perform this conversion.
Diag(Arg->getSourceRange().getBegin(),
diag::err_template_arg_not_convertible)
<< Arg->getType() << InstantiatedParamType << Arg->getSourceRange();
Diag(Param->getLocation(), diag::note_template_param_here);
return true;
return ExprError();
}
QualType IntegerType = Context.getCanonicalType(ParamType);
@ -3527,13 +3528,13 @@ bool Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
// The argument is value-dependent. Create a new
// TemplateArgument with the converted expression.
Converted = TemplateArgument(Arg);
return false;
return Owned(Arg);
}
Converted = TemplateArgument(Value,
ParamType->isEnumeralType() ? ParamType
: IntegerType);
return false;
return Owned(Arg);
}
DeclAccessPair FoundResult; // temporary for ResolveOverloadedFunction
@ -3545,7 +3546,7 @@ bool Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
if (ArgType->isNullPtrType() &&
(ParamType->isPointerType() || ParamType->isMemberPointerType())) {
Converted = TemplateArgument((NamedDecl *)0);
return false;
return Owned(Arg);
}
// Handle pointer-to-function, reference-to-function, and
@ -3577,22 +3578,25 @@ bool Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
true,
FoundResult)) {
if (DiagnoseUseOfDecl(Fn, Arg->getSourceRange().getBegin()))
return true;
return ExprError();
Arg = FixOverloadedFunctionReference(Arg, FoundResult, Fn);
ArgType = Arg->getType();
} else
return true;
return ExprError();
}
if (!ParamType->isMemberPointerType())
return CheckTemplateArgumentAddressOfObjectOrFunction(*this, Param,
ParamType,
Arg, Converted);
if (!ParamType->isMemberPointerType()) {
if (CheckTemplateArgumentAddressOfObjectOrFunction(*this, Param,
ParamType,
Arg, Converted))
return ExprError();
return Owned(Arg);
}
if (IsQualificationConversion(ArgType, ParamType.getNonReferenceType(),
false)) {
ImpCastExprToType(Arg, ParamType, CK_NoOp, CastCategory(Arg));
Arg = ImpCastExprToType(Arg, ParamType, CK_NoOp, CastCategory(Arg)).take();
} else if (!Context.hasSameUnqualifiedType(ArgType,
ParamType.getNonReferenceType())) {
// We can't perform this conversion.
@ -3600,10 +3604,12 @@ bool Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
diag::err_template_arg_not_convertible)
<< Arg->getType() << InstantiatedParamType << Arg->getSourceRange();
Diag(Param->getLocation(), diag::note_template_param_here);
return true;
return ExprError();
}
return CheckTemplateArgumentPointerToMember(Arg, Converted);
if (CheckTemplateArgumentPointerToMember(Arg, Converted))
return ExprError();
return Owned(Arg);
}
if (ParamType->isPointerType()) {
@ -3614,9 +3620,11 @@ bool Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
assert(ParamType->getPointeeType()->isIncompleteOrObjectType() &&
"Only object pointers allowed here");
return CheckTemplateArgumentAddressOfObjectOrFunction(*this, Param,
ParamType,
Arg, Converted);
if (CheckTemplateArgumentAddressOfObjectOrFunction(*this, Param,
ParamType,
Arg, Converted))
return ExprError();
return Owned(Arg);
}
if (const ReferenceType *ParamRefType = ParamType->getAs<ReferenceType>()) {
@ -3635,17 +3643,19 @@ bool Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
true,
FoundResult)) {
if (DiagnoseUseOfDecl(Fn, Arg->getSourceRange().getBegin()))
return true;
return ExprError();
Arg = FixOverloadedFunctionReference(Arg, FoundResult, Fn);
ArgType = Arg->getType();
} else
return true;
return ExprError();
}
return CheckTemplateArgumentAddressOfObjectOrFunction(*this, Param,
ParamType,
Arg, Converted);
if (CheckTemplateArgumentAddressOfObjectOrFunction(*this, Param,
ParamType,
Arg, Converted))
return ExprError();
return Owned(Arg);
}
// -- For a non-type template-parameter of type pointer to data
@ -3655,17 +3665,19 @@ bool Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
if (Context.hasSameUnqualifiedType(ParamType, ArgType)) {
// Types match exactly: nothing more to do here.
} else if (IsQualificationConversion(ArgType, ParamType, false)) {
ImpCastExprToType(Arg, ParamType, CK_NoOp, CastCategory(Arg));
Arg = ImpCastExprToType(Arg, ParamType, CK_NoOp, CastCategory(Arg)).take();
} else {
// We can't perform this conversion.
Diag(Arg->getSourceRange().getBegin(),
diag::err_template_arg_not_convertible)
<< Arg->getType() << InstantiatedParamType << Arg->getSourceRange();
Diag(Param->getLocation(), diag::note_template_param_here);
return true;
return ExprError();
}
return CheckTemplateArgumentPointerToMember(Arg, Converted);
if (CheckTemplateArgumentPointerToMember(Arg, Converted))
return ExprError();
return Owned(Arg);
}
/// \brief Check a template argument against its corresponding
@ -3759,11 +3771,8 @@ Sema::BuildExpressionFromDeclTemplateArgument(const TemplateArgument &Arg,
// the element type on the parameter could be more qualified than the
// element type in the expression we constructed.
if (IsQualificationConversion(((Expr*) RefExpr.get())->getType(),
ParamType.getUnqualifiedType(), false)) {
Expr *RefE = RefExpr.takeAs<Expr>();
ImpCastExprToType(RefE, ParamType.getUnqualifiedType(), CK_NoOp);
RefExpr = Owned(RefE);
}
ParamType.getUnqualifiedType(), false))
RefExpr = ImpCastExprToType(RefExpr.take(), ParamType.getUnqualifiedType(), CK_NoOp);
assert(!RefExpr.isInvalid() &&
Context.hasSameType(((Expr*) RefExpr.get())->getType(),
@ -3782,12 +3791,9 @@ Sema::BuildExpressionFromDeclTemplateArgument(const TemplateArgument &Arg,
if (T->isFunctionType() || T->isArrayType()) {
// Decay functions and arrays.
Expr *RefE = (Expr *)RefExpr.get();
DefaultFunctionArrayConversion(RefE);
if (RefE != RefExpr.get()) {
RefExpr.release();
RefExpr = Owned(RefE);
}
RefExpr = DefaultFunctionArrayConversion(RefExpr.take());
if (RefExpr.isInvalid())
return ExprError();
return move(RefExpr);
}

View File

@ -1154,8 +1154,13 @@ QualType Sema::BuildArrayType(QualType T, ArrayType::ArraySizeModifier ASM,
}
// Do lvalue-to-rvalue conversions on the array size expression.
if (ArraySize && !ArraySize->isRValue())
DefaultLvalueConversion(ArraySize);
if (ArraySize && !ArraySize->isRValue()) {
ExprResult Result = DefaultLvalueConversion(ArraySize);
if (Result.isInvalid())
return QualType();
ArraySize = Result.take();
}
// C99 6.7.5.2p1: The size expression shall have integer type.
// TODO: in theory, if we were insane, we could allow contextual

View File

@ -1373,11 +1373,13 @@ public:
assert(Member->getType()->isRecordType() &&
"unnamed member not of record type?");
if (getSema().PerformObjectMemberConversion(Base,
QualifierLoc.getNestedNameSpecifier(),
FoundDecl, Member))
ExprResult BaseResult =
getSema().PerformObjectMemberConversion(Base,
QualifierLoc.getNestedNameSpecifier(),
FoundDecl, Member);
if (BaseResult.isInvalid())
return ExprError();
Base = BaseResult.take();
ExprValueKind VK = isArrow ? VK_LValue : Base->getValueKind();
MemberExpr *ME =
new (getSema().Context) MemberExpr(Base, isArrow,
@ -1390,7 +1392,10 @@ public:
CXXScopeSpec SS;
SS.Adopt(QualifierLoc);
getSema().DefaultFunctionArrayConversion(Base);
ExprResult BaseResult = getSema().DefaultFunctionArrayConversion(Base);
if (BaseResult.isInvalid())
return ExprError();
Base = BaseResult.take();
QualType BaseType = Base->getType();
// FIXME: this involves duplicating earlier analysis in a lot of
@ -2060,20 +2065,20 @@ public:
bool IsArrow, bool IsFreeIvar) {
// FIXME: We lose track of the IsFreeIvar bit.
CXXScopeSpec SS;
Expr *Base = BaseArg;
ExprResult Base = getSema().Owned(BaseArg);
LookupResult R(getSema(), Ivar->getDeclName(), IvarLoc,
Sema::LookupMemberName);
ExprResult Result = getSema().LookupMemberExpr(R, Base, IsArrow,
/*FIME:*/IvarLoc,
SS, 0,
false);
if (Result.isInvalid())
if (Result.isInvalid() || Base.isInvalid())
return ExprError();
if (Result.get())
return move(Result);
return getSema().BuildMemberReferenceExpr(Base, Base->getType(),
return getSema().BuildMemberReferenceExpr(Base.get(), Base.get()->getType(),
/*FIXME:*/IvarLoc, IsArrow, SS,
/*FirstQualifierInScope=*/0,
R,
@ -2088,20 +2093,20 @@ public:
ObjCPropertyDecl *Property,
SourceLocation PropertyLoc) {
CXXScopeSpec SS;
Expr *Base = BaseArg;
ExprResult Base = getSema().Owned(BaseArg);
LookupResult R(getSema(), Property->getDeclName(), PropertyLoc,
Sema::LookupMemberName);
bool IsArrow = false;
ExprResult Result = getSema().LookupMemberExpr(R, Base, IsArrow,
/*FIME:*/PropertyLoc,
SS, 0, false);
if (Result.isInvalid())
if (Result.isInvalid() || Base.isInvalid())
return ExprError();
if (Result.get())
return move(Result);
return getSema().BuildMemberReferenceExpr(Base, Base->getType(),
return getSema().BuildMemberReferenceExpr(Base.get(), Base.get()->getType(),
/*FIXME:*/PropertyLoc, IsArrow,
SS,
/*FirstQualifierInScope=*/0,
@ -2132,19 +2137,19 @@ public:
ExprResult RebuildObjCIsaExpr(Expr *BaseArg, SourceLocation IsaLoc,
bool IsArrow) {
CXXScopeSpec SS;
Expr *Base = BaseArg;
ExprResult Base = getSema().Owned(BaseArg);
LookupResult R(getSema(), &getSema().Context.Idents.get("isa"), IsaLoc,
Sema::LookupMemberName);
ExprResult Result = getSema().LookupMemberExpr(R, Base, IsArrow,
/*FIME:*/IsaLoc,
SS, 0, false);
if (Result.isInvalid())
if (Result.isInvalid() || Base.isInvalid())
return ExprError();
if (Result.get())
return move(Result);
return getSema().BuildMemberReferenceExpr(Base, Base->getType(),
return getSema().BuildMemberReferenceExpr(Base.get(), Base.get()->getType(),
/*FIXME:*/IsaLoc, IsArrow, SS,
/*FirstQualifierInScope=*/0,
R,
@ -2167,28 +2172,25 @@ public:
// Build a reference to the __builtin_shufflevector builtin
FunctionDecl *Builtin = cast<FunctionDecl>(*Lookup.first);
Expr *Callee
= new (SemaRef.Context) DeclRefExpr(Builtin, Builtin->getType(),
VK_LValue, BuiltinLoc);
SemaRef.UsualUnaryConversions(Callee);
ExprResult Callee
= SemaRef.Owned(new (SemaRef.Context) DeclRefExpr(Builtin, Builtin->getType(),
VK_LValue, BuiltinLoc));
Callee = SemaRef.UsualUnaryConversions(Callee.take());
if (Callee.isInvalid())
return ExprError();
// Build the CallExpr
unsigned NumSubExprs = SubExprs.size();
Expr **Subs = (Expr **)SubExprs.release();
CallExpr *TheCall = new (SemaRef.Context) CallExpr(SemaRef.Context, Callee,
ExprResult TheCall = SemaRef.Owned(
new (SemaRef.Context) CallExpr(SemaRef.Context, Callee.take(),
Subs, NumSubExprs,
Builtin->getCallResultType(),
Expr::getValueKindForType(Builtin->getResultType()),
RParenLoc);
ExprResult OwnedCall(SemaRef.Owned(TheCall));
RParenLoc));
// Type-check the __builtin_shufflevector expression.
ExprResult Result = SemaRef.SemaBuiltinShuffleVector(TheCall);
if (Result.isInvalid())
return ExprError();
OwnedCall.release();
return move(Result);
return SemaRef.SemaBuiltinShuffleVector(cast<CallExpr>(TheCall.take()));
}
/// \brief Build a new template argument pack expansion.