diff options
author | John Wiegley <johnw@boostpro.com> | 2011-04-08 18:41:53 +0000 |
---|---|---|
committer | John Wiegley <johnw@boostpro.com> | 2011-04-08 18:41:53 +0000 |
commit | 429bb276991ff2dbc7c5b438828b9b7737cb15eb (patch) | |
tree | 14890bc7a1e5bb1c92d25f58a67daec2a16c28e0 /lib/Sema/SemaExpr.cpp | |
parent | b7bc34a83aff8af09f2a78aa6d1dcafe18ad8619 (diff) |
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.)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@129143 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaExpr.cpp')
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 1454 |
1 files changed, 818 insertions, 636 deletions
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index a822c45b90..e8488f9ac4 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -256,13 +256,13 @@ SourceRange Sema::getExprRange(ExprTy *E) const { //===----------------------------------------------------------------------===// /// DefaultFunctionArrayConversion (C99 6.3.2.1p3, C99 6.3.2.1p4). -void Sema::DefaultFunctionArrayConversion(Expr *&E) { +ExprResult Sema::DefaultFunctionArrayConversion(Expr *E) { QualType Ty = E->getType(); assert(!Ty.isNull() && "DefaultFunctionArrayConversion - missing type"); if (Ty->isFunctionType()) - ImpCastExprToType(E, Context.getPointerType(Ty), - CK_FunctionToPointerDecay); + E = ImpCastExprToType(E, Context.getPointerType(Ty), + CK_FunctionToPointerDecay).take(); else if (Ty->isArrayType()) { // In C90 mode, arrays only promote to pointers if the array expression is // an lvalue. The relevant legalese is C90 6.2.2.1p3: "an lvalue that has @@ -276,25 +276,29 @@ void Sema::DefaultFunctionArrayConversion(Expr *&E) { // T" can be converted to an rvalue of type "pointer to T". // if (getLangOptions().C99 || getLangOptions().CPlusPlus || E->isLValue()) - ImpCastExprToType(E, Context.getArrayDecayedType(Ty), - CK_ArrayToPointerDecay); + E = ImpCastExprToType(E, Context.getArrayDecayedType(Ty), + CK_ArrayToPointerDecay).take(); } + return Owned(E); } -void Sema::DefaultLvalueConversion(Expr *&E) { +ExprResult Sema::DefaultLvalueConversion(Expr *E) { // C++ [conv.lval]p1: // A glvalue of a non-function, non-array type T can be // converted to a prvalue. - if (!E->isGLValue()) return; + if (!E->isGLValue()) return Owned(E); QualType T = E->getType(); assert(!T.isNull() && "r-value conversion on typeless expression?"); // Create a load out of an ObjCProperty l-value, if necessary. if (E->getObjectKind() == OK_ObjCProperty) { - ConvertPropertyForRValue(E); + ExprResult Res = ConvertPropertyForRValue(E); + if (Res.isInvalid()) + return Owned(E); + E = Res.take(); if (!E->isGLValue()) - return; + return Owned(E); } // We don't want to throw lvalue-to-rvalue casts on top of @@ -303,7 +307,7 @@ void Sema::DefaultLvalueConversion(Expr *&E) { (E->getType() == Context.OverloadTy || T->isDependentType() || T->isRecordType())) - return; + return Owned(E); // The C standard is actually really unclear on this point, and // DR106 tells us what the result should be but not why. It's @@ -311,7 +315,7 @@ void Sema::DefaultLvalueConversion(Expr *&E) { // lvalue-to-rvalue at all. Note that expressions of unqualified // 'void' type are never l-values, but qualified void can be. if (T->isVoidType()) - return; + return Owned(E); // C++ [conv.lval]p1: // [...] If T is a non-class type, the type of the prvalue is the @@ -327,13 +331,18 @@ void Sema::DefaultLvalueConversion(Expr *&E) { CheckArrayAccess(E); - E = ImplicitCastExpr::Create(Context, T, CK_LValueToRValue, - E, 0, VK_RValue); + return Owned(ImplicitCastExpr::Create(Context, T, CK_LValueToRValue, + E, 0, VK_RValue)); } -void Sema::DefaultFunctionArrayLvalueConversion(Expr *&E) { - DefaultFunctionArrayConversion(E); - DefaultLvalueConversion(E); +ExprResult Sema::DefaultFunctionArrayLvalueConversion(Expr *E) { + ExprResult Res = DefaultFunctionArrayConversion(E); + if (Res.isInvalid()) + return ExprError(); + Res = DefaultLvalueConversion(Res.take()); + if (Res.isInvalid()) + return ExprError(); + return move(Res); } @@ -342,9 +351,12 @@ void Sema::DefaultFunctionArrayLvalueConversion(Expr *&E) { /// sometimes surpressed. For example, the array->pointer conversion doesn't /// apply if the array is an argument to the sizeof or address (&) operators. /// In these instances, this routine should *not* be called. -Expr *Sema::UsualUnaryConversions(Expr *&E) { +ExprResult Sema::UsualUnaryConversions(Expr *E) { // First, convert to an r-value. - DefaultFunctionArrayLvalueConversion(E); + ExprResult Res = DefaultFunctionArrayLvalueConversion(E); + if (Res.isInvalid()) + return Owned(E); + E = Res.take(); QualType Ty = E->getType(); assert(!Ty.isNull() && "UsualUnaryConversions - missing type"); @@ -368,60 +380,66 @@ Expr *Sema::UsualUnaryConversions(Expr *&E) { QualType PTy = Context.isPromotableBitField(E); if (!PTy.isNull()) { - ImpCastExprToType(E, PTy, CK_IntegralCast); - return E; + E = ImpCastExprToType(E, PTy, CK_IntegralCast).take(); + return Owned(E); } if (Ty->isPromotableIntegerType()) { QualType PT = Context.getPromotedIntegerType(Ty); - ImpCastExprToType(E, PT, CK_IntegralCast); - return E; + E = ImpCastExprToType(E, PT, CK_IntegralCast).take(); + return Owned(E); } } - - return E; + return Owned(E); } /// DefaultArgumentPromotion (C99 6.5.2.2p6). Used for function calls that /// do not have a prototype. Arguments that have type float are promoted to /// double. All other argument types are converted by UsualUnaryConversions(). -void Sema::DefaultArgumentPromotion(Expr *&Expr) { - QualType Ty = Expr->getType(); +ExprResult Sema::DefaultArgumentPromotion(Expr *E) { + QualType Ty = E->getType(); assert(!Ty.isNull() && "DefaultArgumentPromotion - missing type"); - UsualUnaryConversions(Expr); + ExprResult Res = UsualUnaryConversions(E); + if (Res.isInvalid()) + return Owned(E); + E = Res.take(); // If this is a 'float' (CVR qualified or typedef) promote to double. if (Ty->isSpecificBuiltinType(BuiltinType::Float)) - return ImpCastExprToType(Expr, Context.DoubleTy, CK_FloatingCast); + E = ImpCastExprToType(E, Context.DoubleTy, CK_FloatingCast).take(); + + return Owned(E); } /// DefaultVariadicArgumentPromotion - Like DefaultArgumentPromotion, but /// will warn if the resulting type is not a POD type, and rejects ObjC -/// interfaces passed by value. This returns true if the argument type is -/// completely illegal. -bool Sema::DefaultVariadicArgumentPromotion(Expr *&Expr, VariadicCallType CT, +/// interfaces passed by value. +ExprResult Sema::DefaultVariadicArgumentPromotion(Expr *E, VariadicCallType CT, FunctionDecl *FDecl) { - DefaultArgumentPromotion(Expr); + ExprResult ExprRes = DefaultArgumentPromotion(E); + if (ExprRes.isInvalid()) + return ExprError(); + E = ExprRes.take(); // __builtin_va_start takes the second argument as a "varargs" argument, but // it doesn't actually do anything with it. It doesn't need to be non-pod // etc. if (FDecl && FDecl->getBuiltinID() == Builtin::BI__builtin_va_start) - return false; + return Owned(E); - if (Expr->getType()->isObjCObjectType() && - DiagRuntimeBehavior(Expr->getLocStart(), 0, + if (E->getType()->isObjCObjectType() && + DiagRuntimeBehavior(E->getLocStart(), 0, PDiag(diag::err_cannot_pass_objc_interface_to_vararg) - << Expr->getType() << CT)) - return true; + << E->getType() << CT)) + return ExprError(); - if (!Expr->getType()->isPODType() && - DiagRuntimeBehavior(Expr->getLocStart(), 0, + if (!E->getType()->isPODType() && + DiagRuntimeBehavior(E->getLocStart(), 0, PDiag(diag::warn_cannot_pass_non_pod_arg_to_vararg) - << Expr->getType() << CT)) - return true; + << E->getType() << CT)) + return ExprError(); - return false; + return Owned(E); } /// UsualArithmeticConversions - Performs various conversions that are common to @@ -430,19 +448,24 @@ bool Sema::DefaultVariadicArgumentPromotion(Expr *&Expr, VariadicCallType CT, /// responsible for emitting appropriate error diagnostics. /// FIXME: verify the conversion rules for "complex int" are consistent with /// GCC. -QualType Sema::UsualArithmeticConversions(Expr *&lhsExpr, Expr *&rhsExpr, +QualType Sema::UsualArithmeticConversions(ExprResult &lhsExpr, ExprResult &rhsExpr, bool isCompAssign) { - if (!isCompAssign) - UsualUnaryConversions(lhsExpr); + if (!isCompAssign) { + lhsExpr = UsualUnaryConversions(lhsExpr.take()); + if (lhsExpr.isInvalid()) + return QualType(); + } - UsualUnaryConversions(rhsExpr); + rhsExpr = UsualUnaryConversions(rhsExpr.take()); + if (rhsExpr.isInvalid()) + return QualType(); // For conversion purposes, we ignore any qualifiers. // For example, "const float" and "float" are equivalent. QualType lhs = - Context.getCanonicalType(lhsExpr->getType()).getUnqualifiedType(); + Context.getCanonicalType(lhsExpr.get()->getType()).getUnqualifiedType(); QualType rhs = - Context.getCanonicalType(rhsExpr->getType()).getUnqualifiedType(); + Context.getCanonicalType(rhsExpr.get()->getType()).getUnqualifiedType(); // If both types are identical, no conversion is needed. if (lhs == rhs) @@ -457,11 +480,11 @@ QualType Sema::UsualArithmeticConversions(Expr *&lhsExpr, Expr *&rhsExpr, QualType lhs_unpromoted = lhs; if (lhs->isPromotableIntegerType()) lhs = Context.getPromotedIntegerType(lhs); - QualType LHSBitfieldPromoteTy = Context.isPromotableBitField(lhsExpr); + QualType LHSBitfieldPromoteTy = Context.isPromotableBitField(lhsExpr.get()); if (!LHSBitfieldPromoteTy.isNull()) lhs = LHSBitfieldPromoteTy; if (lhs != lhs_unpromoted && !isCompAssign) - ImpCastExprToType(lhsExpr, lhs, CK_IntegralCast); + lhsExpr = ImpCastExprToType(lhsExpr.take(), lhs, CK_IntegralCast); // If both types are identical, no conversion is needed. if (lhs == rhs) @@ -478,11 +501,11 @@ QualType Sema::UsualArithmeticConversions(Expr *&lhsExpr, Expr *&rhsExpr, if (!RHSComplexFloat && !rhs->isRealFloatingType()) { if (rhs->isIntegerType()) { QualType fp = cast<ComplexType>(lhs)->getElementType(); - ImpCastExprToType(rhsExpr, fp, CK_IntegralToFloating); - ImpCastExprToType(rhsExpr, lhs, CK_FloatingRealToComplex); + rhsExpr = ImpCastExprToType(rhsExpr.take(), fp, CK_IntegralToFloating); + rhsExpr = ImpCastExprToType(rhsExpr.take(), lhs, CK_FloatingRealToComplex); } else { assert(rhs->isComplexIntegerType()); - ImpCastExprToType(rhsExpr, lhs, CK_IntegralComplexToFloatingComplex); + rhsExpr = ImpCastExprToType(rhsExpr.take(), lhs, CK_IntegralComplexToFloatingComplex); } return lhs; } @@ -492,11 +515,11 @@ QualType Sema::UsualArithmeticConversions(Expr *&lhsExpr, Expr *&rhsExpr, // int -> float -> _Complex float if (lhs->isIntegerType()) { QualType fp = cast<ComplexType>(rhs)->getElementType(); - ImpCastExprToType(lhsExpr, fp, CK_IntegralToFloating); - ImpCastExprToType(lhsExpr, rhs, CK_FloatingRealToComplex); + lhsExpr = ImpCastExprToType(lhsExpr.take(), fp, CK_IntegralToFloating); + lhsExpr = ImpCastExprToType(lhsExpr.take(), rhs, CK_FloatingRealToComplex); } else { assert(lhs->isComplexIntegerType()); - ImpCastExprToType(lhsExpr, rhs, CK_IntegralComplexToFloatingComplex); + lhsExpr = ImpCastExprToType(lhsExpr.take(), rhs, CK_IntegralComplexToFloatingComplex); } } return rhs; @@ -518,13 +541,13 @@ QualType Sema::UsualArithmeticConversions(Expr *&lhsExpr, Expr *&rhsExpr, if (LHSComplexFloat && RHSComplexFloat) { if (order > 0) { // _Complex float -> _Complex double - ImpCastExprToType(rhsExpr, lhs, CK_FloatingComplexCast); + rhsExpr = ImpCastExprToType(rhsExpr.take(), lhs, CK_FloatingComplexCast); return lhs; } else if (order < 0) { // _Complex float -> _Complex double if (!isCompAssign) - ImpCastExprToType(lhsExpr, rhs, CK_FloatingComplexCast); + lhsExpr = ImpCastExprToType(lhsExpr.take(), rhs, CK_FloatingComplexCast); return rhs; } return lhs; @@ -536,8 +559,8 @@ QualType Sema::UsualArithmeticConversions(Expr *&lhsExpr, Expr *&rhsExpr, if (order > 0) { // LHS is wider // float -> _Complex double QualType fp = cast<ComplexType>(lhs)->getElementType(); - ImpCastExprToType(rhsExpr, fp, CK_FloatingCast); - ImpCastExprToType(rhsExpr, lhs, CK_FloatingRealToComplex); + rhsExpr = ImpCastExprToType(rhsExpr.take(), fp, CK_FloatingCast); + rhsExpr = ImpCastExprToType(rhsExpr.take(), lhs, CK_FloatingRealToComplex); return lhs; } @@ -545,11 +568,11 @@ QualType Sema::UsualArithmeticConversions(Expr *&lhsExpr, Expr *&rhsExpr, QualType result = (order == 0 ? lhs : Context.getComplexType(rhs)); // double -> _Complex double - ImpCastExprToType(rhsExpr, result, CK_FloatingRealToComplex); + rhsExpr = ImpCastExprToType(rhsExpr.take(), result, CK_FloatingRealToComplex); // _Complex float -> _Complex double if (!isCompAssign && order < 0) - ImpCastExprToType(lhsExpr, result, CK_FloatingComplexCast); + lhsExpr = ImpCastExprToType(lhsExpr.take(), result, CK_FloatingComplexCast); return result; } @@ -562,8 +585,8 @@ QualType Sema::UsualArithmeticConversions(Expr *&lhsExpr, Expr *&rhsExpr, // float -> _Complex double if (!isCompAssign) { QualType fp = cast<ComplexType>(rhs)->getElementType(); - ImpCastExprToType(lhsExpr, fp, CK_FloatingCast); - ImpCastExprToType(lhsExpr, rhs, CK_FloatingRealToComplex); + lhsExpr = ImpCastExprToType(lhsExpr.take(), fp, CK_FloatingCast); + lhsExpr = ImpCastExprToType(lhsExpr.take(), rhs, CK_FloatingRealToComplex); } return rhs; } @@ -573,11 +596,11 @@ QualType Sema::UsualArithmeticConversions(Expr *&lhsExpr, Expr *&rhsExpr, // double -> _Complex double if (!isCompAssign) - ImpCastExprToType(lhsExpr, result, CK_FloatingRealToComplex); + lhsExpr = ImpCastExprToType(lhsExpr.take(), result, CK_FloatingRealToComplex); // _Complex float -> _Complex double if (order > 0) - ImpCastExprToType(rhsExpr, result, CK_FloatingComplexCast); + rhsExpr = ImpCastExprToType(rhsExpr.take(), result, CK_FloatingComplexCast); return result; } @@ -591,13 +614,13 @@ QualType Sema::UsualArithmeticConversions(Expr *&lhsExpr, Expr *&rhsExpr, if (LHSFloat && RHSFloat) { int order = Context.getFloatingTypeOrder(lhs, rhs); if (order > 0) { - ImpCastExprToType(rhsExpr, lhs, CK_FloatingCast); + rhsExpr = ImpCastExprToType(rhsExpr.take(), lhs, CK_FloatingCast); return lhs; } assert(order < 0 && "illegal float comparison"); if (!isCompAssign) - ImpCastExprToType(lhsExpr, rhs, CK_FloatingCast); + lhsExpr = ImpCastExprToType(lhsExpr.take(), rhs, CK_FloatingCast); return rhs; } @@ -605,7 +628,7 @@ QualType Sema::UsualArithmeticConversions(Expr *&lhsExpr, Expr *&rhsExpr, if (LHSFloat) { if (rhs->isIntegerType()) { // Convert rhs to the lhs floating point type. - ImpCastExprToType(rhsExpr, lhs, CK_IntegralToFloating); + rhsExpr = ImpCastExprToType(rhsExpr.take(), lhs, CK_IntegralToFloating); return lhs; } @@ -614,11 +637,11 @@ QualType Sema::UsualArithmeticConversions(Expr *&lhsExpr, Expr *&rhsExpr, QualType result = Context.getComplexType(lhs); // _Complex int -> _Complex float - ImpCastExprToType(rhsExpr, result, CK_IntegralComplexToFloatingComplex); + rhsExpr = ImpCastExprToType(rhsExpr.take(), result, CK_IntegralComplexToFloatingComplex); // float -> _Complex float if (!isCompAssign) - ImpCastExprToType(lhsExpr, result, CK_FloatingRealToComplex); + lhsExpr = ImpCastExprToType(lhsExpr.take(), result, CK_FloatingRealToComplex); return result; } @@ -627,7 +650,7 @@ QualType Sema::UsualArithmeticConversions(Expr *&lhsExpr, Expr *&rhsExpr, if (lhs->isIntegerType()) { // Convert lhs to the rhs floating point type. if (!isCompAssign) - ImpCastExprToType(lhsExpr, rhs, CK_IntegralToFloating); + lhsExpr = ImpCastExprToType(lhsExpr.take(), rhs, CK_IntegralToFloating); return rhs; } @@ -637,10 +660,10 @@ QualType Sema::UsualArithmeticConversions(Expr *&lhsExpr, Expr *&rhsExpr, // _Complex int -> _Complex float if (!isCompAssign) - ImpCastExprToType(lhsExpr, result, CK_IntegralComplexToFloatingComplex); + lhsExpr = ImpCastExprToType(lhsExpr.take(), result, CK_IntegralComplexToFloatingComplex); // float -> _Complex float - ImpCastExprToType(rhsExpr, result, CK_FloatingRealToComplex); + rhsExpr = ImpCastExprToType(rhsExpr.take(), result, CK_FloatingRealToComplex); return result; } @@ -656,21 +679,21 @@ QualType Sema::UsualArithmeticConversions(Expr *&lhsExpr, Expr *&rhsExpr, assert(order && "inequal types with equal element ordering"); if (order > 0) { // _Complex int -> _Complex long - ImpCastExprToType(rhsExpr, lhs, CK_IntegralComplexCast); + rhsExpr = ImpCastExprToType(rhsExpr.take(), lhs, CK_IntegralComplexCast); return lhs; } if (!isCompAssign) - ImpCastExprToType(lhsExpr, rhs, CK_IntegralComplexCast); + lhsExpr = ImpCastExprToType(lhsExpr.take(), rhs, CK_IntegralComplexCast); return rhs; } else if (lhsComplexInt) { // int -> _Complex int - ImpCastExprToType(rhsExpr, lhs, CK_IntegralRealToComplex); + rhsExpr = ImpCastExprToType(rhsExpr.take(), lhs, CK_IntegralRealToComplex); return lhs; } else if (rhsComplexInt) { // int -> _Complex int if (!isCompAssign) - ImpCastExprToType(lhsExpr, rhs, CK_IntegralRealToComplex); + lhsExpr = ImpCastExprToType(lhsExpr.take(), rhs, CK_IntegralRealToComplex); return rhs; } @@ -682,29 +705,29 @@ QualType Sema::UsualArithmeticConversions(Expr *&lhsExpr, Expr *&rhsExpr, if (lhsSigned == rhsSigned) { // Same signedness; use the higher-ranked type if (compare >= 0) { - ImpCastExprToType(rhsExpr, lhs, CK_IntegralCast); + rhsExpr = ImpCastExprToType(rhsExpr.take(), lhs, CK_IntegralCast); return lhs; } else if (!isCompAssign) - ImpCastExprToType(lhsExpr, rhs, CK_IntegralCast); + lhsExpr = ImpCastExprToType(lhsExpr.take(), rhs, CK_IntegralCast); return rhs; } else if (compare != (lhsSigned ? 1 : -1)) { // The unsigned type has greater than or equal rank to the // signed type, so use the unsigned type if (rhsSigned) { - ImpCastExprToType(rhsExpr, lhs, CK_IntegralCast); + rhsExpr = ImpCastExprToType(rhsExpr.take(), lhs, CK_IntegralCast); return lhs; } else if (!isCompAssign) - ImpCastExprToType(lhsExpr, rhs, CK_IntegralCast); + lhsExpr = ImpCastExprToType(lhsExpr.take(), rhs, CK_IntegralCast); return rhs; } else if (Context.getIntWidth(lhs) != Context.getIntWidth(rhs)) { // The two types are different widths; if we are here, that // means the signed type is larger than the unsigned type, so // use the signed type. if (lhsSigned) { - ImpCastExprToType(rhsExpr, lhs, CK_IntegralCast); + rhsExpr = ImpCastExprToType(rhsExpr.take(), lhs, CK_IntegralCast); return lhs; } else if (!isCompAssign) - ImpCastExprToType(lhsExpr, rhs, CK_IntegralCast); + lhsExpr = ImpCastExprToType(lhsExpr.take(), rhs, CK_IntegralCast); return rhs; } else { // The signed type is higher-ranked than the unsigned type, @@ -713,9 +736,9 @@ QualType Sema::UsualArithmeticConversions(Expr *&lhsExpr, Expr *&rhsExpr, // to the signed type. QualType result = Context.getCorrespondingUnsignedType(lhsSigned ? lhs : rhs); - ImpCastExprToType(rhsExpr, result, CK_IntegralCast); + rhsExpr = ImpCastExprToType(rhsExpr.take(), result, CK_IntegralCast); if (!isCompAssign) - ImpCastExprToType(lhsExpr, result, CK_IntegralCast); + lhsExpr = ImpCastExprToType(lhsExpr.take(), result, CK_IntegralCast); return result; } } @@ -1887,13 +1910,14 @@ Sema::LookupInObjCMethod(LookupResult &Lookup, Scope *S, if (SelfExpr.isInvalid()) return ExprError(); - Expr *SelfE = SelfExpr.take(); - DefaultLvalueConversion(SelfE); + SelfExpr = DefaultLvalueConversion(SelfExpr.take()); + if (SelfExpr.isInvalid()) + return ExprError(); MarkDeclarationReferenced(Loc, IV); return Owned(new (Context) ObjCIvarRefExpr(IV, IV->getType(), Loc, - SelfE, true, true)); + SelfExpr.take(), true, true)); } } else if (CurMethod->isInstanceMethod()) { // We should warn if a local variable hides an ivar. @@ -1939,14 +1963,14 @@ Sema::LookupInObjCMethod(LookupResult &Lookup, Scope *S, /// * Finally we cast from the declaring class to the "true" /// declaring class of the member. This conversion does not /// obey access control. -bool -Sema::PerformObjectMemberConversion(Expr *&From, +ExprResult +Sema::PerformObjectMemberConversion(Expr *From, NestedNameSpecifier *Qualifier, NamedDecl *FoundDecl, NamedDecl *Member) { CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(Member->getDeclContext()); if (!RD) - return false; + return Owned(From); QualType DestRecordType; QualType DestType; @@ -1966,7 +1990,7 @@ Sema::PerformObjectMemberConversion(Expr *&From, } } else if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(Member)) { if (Method->isStatic()) - return false; + return Owned(From); DestType = Method->getThisType(Context); DestRecordType = DestType->getPointeeType(); @@ -1980,15 +2004,15 @@ Sema::PerformObjectMemberConversion(Expr *&From, } } else { // No conversion necessary. - return false; + return Owned(From); } if (DestType->isDependentType() || FromType->isDependentType()) - return false; + return Owned(From); // If the unqualified types are the same, no conversion is necessary. if (Context.hasSameUnqualifiedType(FromRecordType, DestRecordType)) - return false; + return Owned(From); SourceRange FromRange = From->getSourceRange(); SourceLocation FromLoc = FromRange.getBegin(); @@ -2027,12 +2051,12 @@ Sema::PerformObjectMemberConversion(Expr *&From, CXXCastPath BasePath; if (CheckDerivedToBaseConversion(FromRecordType, QRecordType, FromLoc, FromRange, &BasePath)) - return true; + return ExprError(); if (PointerConversions) QType = Context.getPointerType(QType); - ImpCastExprToType(From, QType, CK_UncheckedDerivedToBase, - VK, &BasePath); + From = ImpCastExprToType(From, QType, CK_UncheckedDerivedToBase, + VK, &BasePath).take(); FromType = QType; FromRecordType = QRecordType; @@ -2040,7 +2064,7 @@ Sema::PerformObjectMemberConversion(Expr *&From, // If the qualifier type was the same as the destination type, // we're done. if (Context.hasSameUnqualifiedType(FromRecordType, DestRecordType)) - return false; + return Owned(From); } } @@ -2063,13 +2087,13 @@ Sema::PerformObjectMemberConversion(Expr *&From, CXXCastPath BasePath; if (CheckDerivedToBaseConversion(FromRecordType, URecordType, FromLoc, FromRange, &BasePath)) - return true; + return ExprError(); QualType UType = URecordType; if (PointerConversions) UType = Context.getPointerType(UType); - ImpCastExprToType(From, UType, CK_UncheckedDerivedToBase, - VK, &BasePath); + From = ImpCastExprToType(From, UType, CK_UncheckedDerivedToBase, + VK, &BasePath).take(); FromType = UType; FromRecordType = URecordType; } @@ -2083,11 +2107,10 @@ Sema::PerformObjectMemberConversion(Expr *&From, if (CheckDerivedToBaseConversion(FromRecordType, DestRecordType, FromLoc, FromRange, &BasePath, IgnoreAccess)) - return true; + return ExprError(); - ImpCastExprToType(From, DestType, CK_UncheckedDerivedToBase, - VK, &BasePath); - return false; + return ImpCastExprToType(From, DestType, CK_UncheckedDerivedToBase, + VK, &BasePath); } /// \brief Build a MemberExpr AST node. @@ -2153,10 +2176,12 @@ BuildFieldReferenceExpr(Sema &S, Expr *BaseExpr, bool IsArrow, } S.MarkDeclarationReferenced(MemberNameInfo.getLoc(), Field); - if (S.PerformObjectMemberConversion(BaseExpr, SS.getScopeRep(), - FoundDecl, Field)) + ExprResult Base = + S.PerformObjectMemberConversion(BaseExpr, SS.getScopeRep(), + FoundDecl, Field); + if (Base.isInvalid()) return ExprError(); - return S.Owned(BuildMemberExpr(S.Context, BaseExpr, IsArrow, SS, + return S.Owned(BuildMemberExpr(S.Context, Base.take(), IsArrow, SS, Field, FoundDecl, MemberNameInfo, MemberType, VK, OK)); } @@ -2638,10 +2663,10 @@ ExprResult Sema::ActOnNumericConstant(const Token &Tok) { if (Ty == Context.DoubleTy) { if (getLangOptions().SinglePrecisionConstants) { - ImpCastExprToType(Res, Context.FloatTy, CK_FloatingCast); + Res = ImpCastExprToType(Res, Context.FloatTy, CK_FloatingCast).take(); } else if (getLangOptions().OpenCL && !getOpenCLOptions().cl_khr_fp64) { Diag(Tok.getLocation(), diag::warn_double_const_requires_fp64); - ImpCastExprToType(Res, Context.FloatTy, CK_FloatingCast); + Res = ImpCastExprToType(Res, Context.FloatTy, CK_FloatingCast).take(); } } } else if (!Literal.isIntegerLiteral()) { @@ -2931,33 +2956,36 @@ Sema::ActOnUnaryExprOrTypeTraitExpr(SourceLocation OpLoc, return move(Result); } -static QualType CheckRealImagOperand(Sema &S, Expr *&V, SourceLocation Loc, +static QualType CheckRealImagOperand(Sema &S, ExprResult &V, SourceLocation Loc, bool isReal) { - if (V->isTypeDependent()) + if (V.get()->isTypeDependent()) return S.Context.DependentTy; // _Real and _Imag are only l-values for normal l-values. - if (V->getObjectKind() != OK_Ordinary) - S.DefaultLvalueConversion(V); + if (V.get()->getObjectKind() != OK_Ordinary) { + V = S.DefaultLvalueConversion(V.take()); + if (V.isInvalid()) + return QualType(); + } // These operators return the element type of a complex type. - if (const ComplexType *CT = V->getType()->getAs<ComplexType>()) + if (const ComplexType *CT = V.get()->getType()->getAs<ComplexType>()) return CT->getElementType(); // Otherwise they pass through real integer and floating point types here. - if (V->getType()->isArithmeticType()) - return V->getType(); + if (V.get()->getType()->isArithmeticType()) + return V.get()->getType(); // Test for placeholders. - ExprResult PR = S.CheckPlaceholderExpr(V, Loc); + ExprResult PR = S.CheckPlaceholderExpr(V.get(), Loc); if (PR.isInvalid()) return QualType(); - if (PR.take() != V) { - V = PR.take(); + if (PR.get() != V.get()) { + V = move(PR); return CheckRealImagOperand(S, V, Loc, isReal); } // Reject anything else. - S.Diag(Loc, diag::err_realimag_invalid_type) << V->getType() + S.Diag(Loc, diag::err_realimag_invalid_type) << V.get()->getType() << (isReal ? "__real" : "__imag"); return QualType(); } @@ -3027,9 +3055,16 @@ Sema::CreateBuiltinArraySubscriptExpr(Expr *Base, SourceLocation LLoc, Expr *RHSExp = Idx; // Perform default conversions. - if (!LHSExp->getType()->getAs<VectorType>()) - DefaultFunctionArrayLvalueConversion(LHSExp); - DefaultFunctionArrayLvalueConversion(RHSExp); + if (!LHSExp->getType()->getAs<VectorType>()) { + ExprResult Result = DefaultFunctionArrayLvalueConversion(LHSExp); + if (Result.isInvalid()) + return ExprError(); + LHSExp = Result.take(); + } + ExprResult Result = DefaultFunctionArrayLvalueConversion(RHSExp); + if (Result.isInvalid()) + return ExprError(); + RHSExp = Result.take(); QualType LHSTy = LHSExp->getType(), RHSTy = RHSExp->getType(); ExprValueKind VK = VK_LValue; @@ -3082,8 +3117,8 @@ Sema::CreateBuiltinArraySubscriptExpr(Expr *Base, SourceLocation LLoc, // force the promotion here. Diag(LHSExp->getLocStart(), diag::ext_subscript_non_lvalue) << LHSExp->getSourceRange(); - ImpCastExprToType(LHSExp, Context.getArrayDecayedType(LHSTy), - CK_ArrayToPointerDecay); + LHSExp = ImpCastExprToType(LHSExp, Context.getArrayDecayedType(LHSTy), + CK_ArrayToPointerDecay).take(); LHSTy = LHSExp->getType(); BaseExpr = LHSExp; @@ -3093,8 +3128,8 @@ Sema::CreateBuiltinArraySubscriptExpr(Expr *Base, SourceLocation LLoc, // Same as previous, except for 123[f().a] case Diag(RHSExp->getLocStart(), diag::ext_subscript_non_lvalue) << RHSExp->getSourceRange(); - ImpCastExprToType(RHSExp, Context.getArrayDecayedType(RHSTy), - CK_ArrayToPointerDecay); + RHSExp = ImpCastExprToType(RHSExp, Context.getArrayDecayedType(RHSTy), + CK_ArrayToPointerDecay).take(); RHSTy = RHSExp->getType(); BaseExpr = RHSExp; @@ -3512,10 +3547,15 @@ Sema::BuildMemberReferenceExpr(Expr *Base, QualType BaseType, // Explicit member accesses. } else { + ExprResult BaseResult = Owned(Base); ExprResult Result = - LookupMemberExpr(R, Base, IsArrow, OpLoc, + LookupMemberExpr(R, BaseResult, IsArrow, OpLoc, SS, /*ObjCImpDecl*/ 0, TemplateArgs != 0); + if (BaseResult.isInvalid()) + return ExprError(); + Base = BaseResult.take(); + if (Result.isInvalid()) { Owned(Base); return ExprError(); @@ -3639,8 +3679,12 @@ Sema::BuildMemberReferenceExpr(Expr *BaseExpr, QualType BaseExprType, // Perform a property load on the base regardless of whether we // actually need it for the declaration. - if (BaseExpr->getObjectKind() == OK_ObjCProperty) - ConvertPropertyForRValue(BaseExpr); + if (BaseExpr->getObjectKind() == OK_ObjCProperty) { + ExprResult Result = ConvertPropertyForRValue(BaseExpr); + if (Result.isInvalid()) + return ExprError(); + BaseExpr = Result.take(); + } if (FieldDecl *FD = dyn_cast<FieldDecl>(MemberDecl)) return BuildFieldReferenceExpr(*this, BaseExpr, IsArrow, @@ -3699,9 +3743,9 @@ Sema::BuildMemberReferenceExpr(Expr *BaseExpr, QualType BaseExprType, /// types would be profitable. The redefinition type is whatever /// this translation unit tried to typedef to id/Class; we store /// it to the side and then re-use it in places like this. -static bool ShouldTryAgainWithRedefinitionType(Sema &S, Expr *&base) { +static bool ShouldTryAgainWithRedefinitionType(Sema &S, ExprResult &base) { const ObjCObjectPointerType *opty - = base->getType()->getAs<ObjCObjectPointerType>(); + = base.get()->getType()->getAs<ObjCObjectPointerType>(); if (!opty) return false; const ObjCObjectType *ty = opty->getObjectType(); @@ -3721,7 +3765,7 @@ static bool ShouldTryAgainWithRedefinitionType(Sema &S, Expr *&base) { if (opty && !opty->getObjectType()->getInterface() != 0) return false; - S.ImpCastExprToType(base, redef, CK_BitCast); + base = S.ImpCastExprToType(base.take(), redef, CK_BitCast); return true; } @@ -3736,17 +3780,22 @@ static bool ShouldTryAgainWithRedefinitionType(Sema &S, Expr *&base) { /// The ObjCImpDecl bit is a gross hack that will need to be properly /// fixed for ObjC++. ExprResult -Sema::LookupMemberExpr(LookupResult &R, Expr *&BaseExpr, +Sema::LookupMemberExpr(LookupResult &R, ExprResult &BaseExpr, bool &IsArrow, SourceLocation OpLoc, CXXScopeSpec &SS, Decl *ObjCImpDecl, bool HasTemplateArgs) { - assert(BaseExpr && "no base expression"); + assert(BaseExpr.get() && "no base expression"); // Perform default conversions. - DefaultFunctionArrayConversion(BaseExpr); - if (IsArrow) DefaultLvalueConversion(BaseExpr); + BaseExpr = DefaultFunctionArrayConversion(BaseExpr.take()); + + if (IsArrow) { + BaseExpr = DefaultLvalueConversion(BaseExpr.take()); + if (BaseExpr.isInvalid()) + return ExprError(); + } - QualType BaseType = BaseExpr->getType(); + QualType BaseType = BaseExpr.get()->getType(); assert(!BaseType->isDependentType()); DeclarationName MemberName = R.getLookupName(); @@ -3770,19 +3819,19 @@ Sema::LookupMemberExpr(LookupResult &R, Expr *&BaseExpr, // overloaded operator->, but that should have been dealt with // by now. Diag(OpLoc, diag::err_typecheck_member_reference_suggestion) - << BaseType << int(IsArrow) << BaseExpr->getSourceRange() + << BaseType << int(IsArrow) << BaseExpr.get()->getSourceRange() << FixItHint::CreateReplacement(OpLoc, "."); IsArrow = false; } else { Diag(MemberLoc, diag::err_typecheck_member_reference_arrow) - << BaseType << BaseExpr->getSourceRange(); + << BaseType << BaseExpr.get()->getSourceRange(); return ExprError(); } } // Handle field access to simple records. if (const RecordType *RTy = BaseType->getAs<RecordType>()) { - if (LookupMemberExprInRecord(*this, R, BaseExpr->getSourceRange(), + if (LookupMemberExprInRecord(*this, R, BaseExpr.get()->getSourceRange(), RTy, OpLoc, SS, HasTemplateArgs)) return ExprError(); @@ -3805,7 +3854,7 @@ Sema::LookupMemberExpr(LookupResult &R, Expr *&BaseExpr, // But we only actually find it this way on objects of type 'id', // apparently. if (OTy->isObjCId() && Member->isStr("isa")) - return Owned(new (Context) ObjCIsaExpr(BaseExpr, IsArrow, MemberLoc, + return Owned(new (Context) ObjCIsaExpr(BaseExpr.take(), IsArrow, MemberLoc, Context.getObjCClassType())); if (ShouldTryAgainWithRedefinitionType(*this, BaseExpr)) @@ -3838,7 +3887,7 @@ Sema::LookupMemberExpr(LookupResult &R, Expr *&BaseExpr, Diag(MemberLoc, diag::err_typecheck_member_reference_ivar) << IDecl->getDeclName() << MemberName - << BaseExpr->getSourceRange(); + << BaseExpr.get()->getSourceRange(); return ExprError(); } } @@ -3884,7 +3933,7 @@ Sema::LookupMemberExpr(LookupResult &R, Expr *&BaseExpr, } return Owned(new (Context) ObjCIvarRefExpr(IV, IV->getType(), - MemberLoc, BaseExpr, + MemberLoc, BaseExpr.take(), IsArrow)); } @@ -3892,8 +3941,11 @@ Sema::LookupMemberExpr(LookupResult &R, Expr *&BaseExpr, const ObjCObjectPointerType *OPT; if (!IsArrow && (OPT = BaseType->getAs<ObjCObjectPointerType>())) { // This actually uses the base as an r-value. - DefaultLvalueConversion(BaseExpr); - assert(Context.hasSameUnqualifiedType(BaseType, BaseExpr->getType())); + BaseExpr = DefaultLvalueConversion(BaseExpr.take()); + if (BaseExpr.isInvalid()) + return ExprError(); + + assert(Context.hasSameUnqualifiedType(BaseType, BaseExpr.get()->getType())); IdentifierInfo *Member = MemberName.getAsIdentifierInfo(); @@ -3913,7 +3965,7 @@ Sema::LookupMemberExpr(LookupResult &R, Expr *&BaseExpr, VK_LValue, OK_ObjCProperty, MemberLoc, - BaseExpr)); + BaseExpr.take())); } if (ObjCMethodDecl *OMD = dyn_cast<O |