diff options
Diffstat (limited to 'lib/Sema/SemaExpr.cpp')
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 976 |
1 files changed, 647 insertions, 329 deletions
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index bf4abfc..76330f5 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -12,13 +12,9 @@ //===----------------------------------------------------------------------===// #include "clang/Sema/SemaInternal.h" -#include "clang/Sema/DelayedDiagnostic.h" -#include "clang/Sema/Initialization.h" -#include "clang/Sema/Lookup.h" -#include "clang/Sema/ScopeInfo.h" -#include "clang/Sema/AnalysisBasedWarnings.h" -#include "clang/AST/ASTContext.h" +#include "TreeTransform.h" #include "clang/AST/ASTConsumer.h" +#include "clang/AST/ASTContext.h" #include "clang/AST/ASTMutationListener.h" #include "clang/AST/CXXInheritance.h" #include "clang/AST/DeclObjC.h" @@ -34,14 +30,17 @@ #include "clang/Basic/TargetInfo.h" #include "clang/Lex/LiteralSupport.h" #include "clang/Lex/Preprocessor.h" +#include "clang/Sema/AnalysisBasedWarnings.h" #include "clang/Sema/DeclSpec.h" +#include "clang/Sema/DelayedDiagnostic.h" #include "clang/Sema/Designator.h" +#include "clang/Sema/Initialization.h" +#include "clang/Sema/Lookup.h" +#include "clang/Sema/ParsedTemplate.h" #include "clang/Sema/Scope.h" #include "clang/Sema/ScopeInfo.h" -#include "clang/Sema/ParsedTemplate.h" #include "clang/Sema/SemaFixItUtils.h" #include "clang/Sema/Template.h" -#include "TreeTransform.h" using namespace clang; using namespace sema; @@ -163,7 +162,7 @@ static bool hasAnyExplicitStorageClass(const FunctionDecl *D) { for (FunctionDecl::redecl_iterator I = D->redecls_begin(), E = D->redecls_end(); I != E; ++I) { - if (I->getStorageClassAsWritten() != SC_None) + if (I->getStorageClass() != SC_None) return true; } return false; @@ -215,19 +214,24 @@ static void diagnoseUseOfInternalDeclInInlineFunction(Sema &S, : diag::warn_internal_in_extern_inline) << /*IsVar=*/!UsedFn << D; - // Suggest "static" on the inline function, if possible. - if (!hasAnyExplicitStorageClass(Current)) { - const FunctionDecl *FirstDecl = Current->getCanonicalDecl(); - SourceLocation DeclBegin = FirstDecl->getSourceRange().getBegin(); - S.Diag(DeclBegin, diag::note_convert_inline_to_static) - << Current << FixItHint::CreateInsertion(DeclBegin, "static "); - } + S.MaybeSuggestAddingStaticToDecl(Current); S.Diag(D->getCanonicalDecl()->getLocation(), diag::note_internal_decl_declared_here) << D; } +void Sema::MaybeSuggestAddingStaticToDecl(const FunctionDecl *Cur) { + const FunctionDecl *First = Cur->getFirstDeclaration(); + + // Suggest "static" on the function, if possible. + if (!hasAnyExplicitStorageClass(First)) { + SourceLocation DeclBegin = First->getSourceRange().getBegin(); + Diag(DeclBegin, diag::note_convert_inline_to_static) + << Cur << FixItHint::CreateInsertion(DeclBegin, "static "); + } +} + /// \brief Determine whether the use of this declaration is valid, and /// emit any corresponding diagnostics. /// @@ -288,12 +292,6 @@ bool Sema::DiagnoseUseOfDecl(NamedDecl *D, SourceLocation Loc, /// diagnostic complaining about the given function being deleted or /// unavailable. std::string Sema::getDeletedOrUnavailableSuffix(const FunctionDecl *FD) { - // FIXME: C++0x implicitly-deleted special member functions could be - // detected here so that we could improve diagnostics to say, e.g., - // "base class 'A' had a deleted copy constructor". - if (FD->isDeleted()) - return std::string(); - std::string Message; if (FD->getAvailability(&Message)) return ": " + Message; @@ -457,6 +455,62 @@ static void CheckForNullPointerDereference(Sema &S, Expr *E) { } } +static void DiagnoseDirectIsaAccess(Sema &S, const ObjCIvarRefExpr *OIRE, + SourceLocation AssignLoc, + const Expr* RHS) { + const ObjCIvarDecl *IV = OIRE->getDecl(); + if (!IV) + return; + + DeclarationName MemberName = IV->getDeclName(); + IdentifierInfo *Member = MemberName.getAsIdentifierInfo(); + if (!Member || !Member->isStr("isa")) + return; + + const Expr *Base = OIRE->getBase(); + QualType BaseType = Base->getType(); + if (OIRE->isArrow()) + BaseType = BaseType->getPointeeType(); + if (const ObjCObjectType *OTy = BaseType->getAs<ObjCObjectType>()) + if (ObjCInterfaceDecl *IDecl = OTy->getInterface()) { + ObjCInterfaceDecl *ClassDeclared = 0; + ObjCIvarDecl *IV = IDecl->lookupInstanceVariable(Member, ClassDeclared); + if (!ClassDeclared->getSuperClass() + && (*ClassDeclared->ivar_begin()) == IV) { + if (RHS) { + NamedDecl *ObjectSetClass = + S.LookupSingleName(S.TUScope, + &S.Context.Idents.get("object_setClass"), + SourceLocation(), S.LookupOrdinaryName); + if (ObjectSetClass) { + SourceLocation RHSLocEnd = S.PP.getLocForEndOfToken(RHS->getLocEnd()); + S.Diag(OIRE->getExprLoc(), diag::warn_objc_isa_assign) << + FixItHint::CreateInsertion(OIRE->getLocStart(), "object_setClass(") << + FixItHint::CreateReplacement(SourceRange(OIRE->getOpLoc(), + AssignLoc), ",") << + FixItHint::CreateInsertion(RHSLocEnd, ")"); + } + else + S.Diag(OIRE->getLocation(), diag::warn_objc_isa_assign); + } else { + NamedDecl *ObjectGetClass = + S.LookupSingleName(S.TUScope, + &S.Context.Idents.get("object_getClass"), + SourceLocation(), S.LookupOrdinaryName); + if (ObjectGetClass) + S.Diag(OIRE->getExprLoc(), diag::warn_objc_isa_use) << + FixItHint::CreateInsertion(OIRE->getLocStart(), "object_getClass(") << + FixItHint::CreateReplacement( + SourceRange(OIRE->getOpLoc(), + OIRE->getLocEnd()), ")"); + else + S.Diag(OIRE->getLocation(), diag::warn_objc_isa_use); + } + S.Diag(IV->getLocation(), diag::note_ivar_decl); + } + } +} + ExprResult Sema::DefaultLvalueConversion(Expr *E) { // Handle any placeholder expressions which made it here. if (E->getType()->isPlaceholderType()) { @@ -489,8 +543,31 @@ ExprResult Sema::DefaultLvalueConversion(Expr *E) { if (T->isVoidType()) return Owned(E); - CheckForNullPointerDereference(*this, E); + // OpenCL usually rejects direct accesses to values of 'half' type. + if (getLangOpts().OpenCL && !getOpenCLOptions().cl_khr_fp16 && + T->isHalfType()) { + Diag(E->getExprLoc(), diag::err_opencl_half_load_store) + << 0 << T; + return ExprError(); + } + CheckForNullPointerDereference(*this, E); + if (const ObjCIsaExpr *OISA = dyn_cast<ObjCIsaExpr>(E->IgnoreParenCasts())) { + NamedDecl *ObjectGetClass = LookupSingleName(TUScope, + &Context.Idents.get("object_getClass"), + SourceLocation(), LookupOrdinaryName); + if (ObjectGetClass) + Diag(E->getExprLoc(), diag::warn_objc_isa_use) << + FixItHint::CreateInsertion(OISA->getLocStart(), "object_getClass(") << + FixItHint::CreateReplacement( + SourceRange(OISA->getOpLoc(), OISA->getIsaMemberLoc()), ")"); + else + Diag(E->getExprLoc(), diag::warn_objc_isa_use); + } + else if (const ObjCIvarRefExpr *OIRE = + dyn_cast<ObjCIvarRefExpr>(E->IgnoreParenCasts())) + DiagnoseDirectIsaAccess(*this, OIRE, SourceLocation(), /* Expr*/0); + // C++ [conv.lval]p1: // [...] If T is a non-class type, the type of the prvalue is the // cv-unqualified version of T. Otherwise, the type of the @@ -504,6 +581,12 @@ ExprResult Sema::DefaultLvalueConversion(Expr *E) { T = T.getUnqualifiedType(); UpdateMarkingForLValueToRValue(E); + + // Loading a __weak object implicitly retains the value, so we need a cleanup to + // balance that. + if (getLangOpts().ObjCAutoRefCount && + E->getType().getObjCLifetime() == Qualifiers::OCL_Weak) + ExprNeedsCleanups = true; ExprResult Res = Owned(ImplicitCastExpr::Create(Context, T, CK_LValueToRValue, E, 0, VK_RValue)); @@ -540,15 +623,14 @@ ExprResult Sema::UsualUnaryConversions(Expr *E) { // First, convert to an r-value. ExprResult Res = DefaultFunctionArrayLvalueConversion(E); if (Res.isInvalid()) - return Owned(E); + return ExprError(); E = Res.take(); QualType Ty = E->getType(); assert(!Ty.isNull() && "UsualUnaryConversions - missing type"); - // Half FP is a bit different: it's a storage-only type, meaning that any - // "use" of it should be promoted to float. - if (Ty->isHalfType()) + // Half FP have to be promoted to float unless it is natively supported + if (Ty->isHalfType() && !getLangOpts().NativeHalfType) return ImpCastExprToType(Res.take(), Context.FloatTy, CK_FloatingCast); // Try to perform integral promotions if the object has a theoretically @@ -583,19 +665,23 @@ ExprResult Sema::UsualUnaryConversions(Expr *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(). +/// do not have a prototype. Arguments that have type float or __fp16 +/// are promoted to double. All other argument types are converted by +/// UsualUnaryConversions(). ExprResult Sema::DefaultArgumentPromotion(Expr *E) { QualType Ty = E->getType(); assert(!Ty.isNull() && "DefaultArgumentPromotion - missing type"); ExprResult Res = UsualUnaryConversions(E); if (Res.isInvalid()) - return Owned(E); + return ExprError(); E = Res.take(); - // If this is a 'float' (CVR qualified or typedef) promote to double. - if (Ty->isSpecificBuiltinType(BuiltinType::Float)) + // If this is a 'float' or '__fp16' (CVR qualified or typedef) promote to + // double. + const BuiltinType *BTy = Ty->getAs<BuiltinType>(); + if (BTy && (BTy->getKind() == BuiltinType::Half || + BTy->getKind() == BuiltinType::Float)) E = ImpCastExprToType(E, Context.DoubleTy, CK_FloatingCast).take(); // C++ performs lvalue-to-rvalue conversion as a default argument @@ -635,16 +721,16 @@ Sema::VarArgKind Sema::isValidVarArgType(const QualType &Ty) { if (Ty.isCXX98PODType(Context)) return VAK_Valid; - // C++0x [expr.call]p7: - // Passing a potentially-evaluated argument of class type (Clause 9) + // C++11 [expr.call]p7: + // Passing a potentially-evaluated argument of class type (Clause 9) // having a non-trivial copy constructor, a non-trivial move constructor, - // or a non-trivial destructor, with no corresponding parameter, + // or a non-trivial destructor, with no corresponding parameter, // is conditionally-supported with implementation-defined semantics. - if (getLangOpts().CPlusPlus0x && !Ty->isDependentType()) + if (getLangOpts().CPlusPlus11 && !Ty->isDependentType()) if (CXXRecordDecl *Record = Ty->getAsCXXRecordDecl()) - if (Record->hasTrivialCopyConstructor() && - Record->hasTrivialMoveConstructor() && - Record->hasTrivialDestructor()) + if (!Record->hasNonTrivialCopyConstructor() && + !Record->hasNonTrivialMoveConstructor() && + !Record->hasNonTrivialDestructor()) return VAK_ValidInCXX11; if (getLangOpts().ObjCAutoRefCount && Ty->isObjCLifetimeType()) @@ -673,7 +759,7 @@ bool Sema::variadicArgumentPODCheck(const Expr *E, VariadicCallType CT) { return DiagRuntimeBehavior(E->getLocStart(), 0, PDiag(diag::warn_cannot_pass_non_pod_arg_to_vararg) - << getLangOpts().CPlusPlus0x << Ty << CT); + << getLangOpts().CPlusPlus11 << Ty << CT); } } // c++ rules are enforced elsewhere. @@ -938,54 +1024,24 @@ static QualType handleFloatConversion(Sema &S, ExprResult &LHS, /*convertFloat=*/!IsCompAssign); } -/// \brief Handle conversions with GCC complex int extension. Helper function -/// of UsualArithmeticConversions() -// FIXME: if the operands are (int, _Complex long), we currently -// don't promote the complex. Also, signedness? -static QualType handleComplexIntConversion(Sema &S, ExprResult &LHS, - ExprResult &RHS, QualType LHSType, - QualType RHSType, - bool IsCompAssign) { - const ComplexType *LHSComplexInt = LHSType->getAsComplexIntegerType(); - const ComplexType *RHSComplexInt = RHSType->getAsComplexIntegerType(); +typedef ExprResult PerformCastFn(Sema &S, Expr *operand, QualType toType); - if (LHSComplexInt && RHSComplexInt) { - int order = S.Context.getIntegerTypeOrder(LHSComplexInt->getElementType(), - RHSComplexInt->getElementType()); - assert(order && "inequal types with equal element ordering"); - if (order > 0) { - // _Complex int -> _Complex long - RHS = S.ImpCastExprToType(RHS.take(), LHSType, CK_IntegralComplexCast); - return LHSType; - } - - if (!IsCompAssign) - LHS = S.ImpCastExprToType(LHS.take(), RHSType, CK_IntegralComplexCast); - return RHSType; - } - - if (LHSComplexInt) { - // int -> _Complex int - // FIXME: This needs to take integer ranks into account - RHS = S.ImpCastExprToType(RHS.take(), LHSComplexInt->getElementType(), - CK_IntegralCast); - RHS = S.ImpCastExprToType(RHS.take(), LHSType, CK_IntegralRealToComplex); - return LHSType; - } +namespace { +/// These helper callbacks are placed in an anonymous namespace to +/// permit their use as function template parameters. +ExprResult doIntegralCast(Sema &S, Expr *op, QualType toType) { + return S.ImpCastExprToType(op, toType, CK_IntegralCast); +} - assert(RHSComplexInt); - // int -> _Complex int - // FIXME: This needs to take integer ranks into account - if (!IsCompAssign) { - LHS = S.ImpCastExprToType(LHS.take(), RHSComplexInt->getElementType(), - CK_IntegralCast); - LHS = S.ImpCastExprToType(LHS.take(), RHSType, CK_IntegralRealToComplex); - } - return RHSType; +ExprResult doComplexIntegralCast(Sema &S, Expr *op, QualType toType) { + return S.ImpCastExprToType(op, S.Context.getComplexType(toType), + CK_IntegralComplexCast); +} } /// \brief Handle integer arithmetic conversions. Helper function of /// UsualArithmeticConversions() +template <PerformCastFn doLHSCast, PerformCastFn doRHSCast> static QualType handleIntegerConversion(Sema &S, ExprResult &LHS, ExprResult &RHS, QualType LHSType, QualType RHSType, bool IsCompAssign) { @@ -996,29 +1052,29 @@ static QualType handleIntegerConversion(Sema &S, ExprResult &LHS, if (LHSSigned == RHSSigned) { // Same signedness; use the higher-ranked type if (order >= 0) { - RHS = S.ImpCastExprToType(RHS.take(), LHSType, CK_IntegralCast); + RHS = (*doRHSCast)(S, RHS.take(), LHSType); return LHSType; } else if (!IsCompAssign) - LHS = S.ImpCastExprToType(LHS.take(), RHSType, CK_IntegralCast); + LHS = (*doLHSCast)(S, LHS.take(), RHSType); return RHSType; } else if (order != (LHSSigned ? 1 : -1)) { // The unsigned type has greater than or equal rank to the // signed type, so use the unsigned type if (RHSSigned) { - RHS = S.ImpCastExprToType(RHS.take(), LHSType, CK_IntegralCast); + RHS = (*doRHSCast)(S, RHS.take(), LHSType); return LHSType; } else if (!IsCompAssign) - LHS = S.ImpCastExprToType(LHS.take(), RHSType, CK_IntegralCast); + LHS = (*doLHSCast)(S, LHS.take(), RHSType); return RHSType; } else if (S.Context.getIntWidth(LHSType) != S.Context.getIntWidth(RHSType)) { // 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) { - RHS = S.ImpCastExprToType(RHS.take(), LHSType, CK_IntegralCast); + RHS = (*doRHSCast)(S, RHS.take(), LHSType); return LHSType; } else if (!IsCompAssign) - LHS = S.ImpCastExprToType(LHS.take(), RHSType, CK_IntegralCast); + LHS = (*doLHSCast)(S, LHS.take(), RHSType); return RHSType; } else { // The signed type is higher-ranked than the unsigned type, @@ -1027,19 +1083,62 @@ static QualType handleIntegerConversion(Sema &S, ExprResult &LHS, // to the signed type. QualType result = S.Context.getCorrespondingUnsignedType(LHSSigned ? LHSType : RHSType); - RHS = S.ImpCastExprToType(RHS.take(), result, CK_IntegralCast); + RHS = (*doRHSCast)(S, RHS.take(), result); if (!IsCompAssign) - LHS = S.ImpCastExprToType(LHS.take(), result, CK_IntegralCast); + LHS = (*doLHSCast)(S, LHS.take(), result); return result; } } +/// \brief Handle conversions with GCC complex int extension. Helper function +/// of UsualArithmeticConversions() +static QualType handleComplexIntConversion(Sema &S, ExprResult &LHS, + ExprResult &RHS, QualType LHSType, + QualType RHSType, + bool IsCompAssign) { + const ComplexType *LHSComplexInt = LHSType->getAsComplexIntegerType(); + const ComplexType *RHSComplexInt = RHSType->getAsComplexIntegerType(); + + if (LHSComplexInt && RHSComplexInt) { + QualType LHSEltType = LHSComplexInt->getElementType(); + QualType RHSEltType = RHSComplexInt->getElementType(); + QualType ScalarType = + handleIntegerConversion<doComplexIntegralCast, doComplexIntegralCast> + (S, LHS, RHS, LHSEltType, RHSEltType, IsCompAssign); + + return S.Context.getComplexType(ScalarType); + } + + if (LHSComplexInt) { + QualType LHSEltType = LHSComplexInt->getElementType(); + QualType ScalarType = + handleIntegerConversion<doComplexIntegralCast, doIntegralCast> + (S, LHS, RHS, LHSEltType, RHSType, IsCompAssign); + QualType ComplexType = S.Context.getComplexType(ScalarType); + RHS = S.ImpCastExprToType(RHS.take(), ComplexType, + CK_IntegralRealToComplex); + + return ComplexType; + } + + assert(RHSComplexInt); + + QualType RHSEltType = RHSComplexInt->getElementType(); + QualType ScalarType = + handleIntegerConversion<doIntegralCast, doComplexIntegralCast> + (S, LHS, RHS, LHSType, RHSEltType, IsCompAssign); + QualType ComplexType = S.Context.getComplexType(ScalarType); + + if (!IsCompAssign) + LHS = S.ImpCastExprToType(LHS.take(), ComplexType, + CK_IntegralRealToComplex); + return ComplexType; +} + /// UsualArithmeticConversions - Performs 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. -/// FIXME: verify the conversion rules for "complex int" are consistent with -/// GCC. QualType Sema::UsualArithmeticConversions(ExprResult &LHS, ExprResult &RHS, bool IsCompAssign) { if (!IsCompAssign) { @@ -1104,10 +1203,11 @@ QualType Sema::UsualArithmeticConversions(ExprResult &LHS, ExprResult &RHS, IsCompAssign); // Finally, we have two differing integer types. - return handleIntegerConversion(*this, LHS, RHS, LHSType, RHSType, - IsCompAssign); + return handleIntegerConversion<doIntegralCast, doIntegralCast> + (*this, LHS, RHS, LHSType, RHSType, IsCompAssign); } + //===----------------------------------------------------------------------===// // Semantic Analysis for various Expression Types //===----------------------------------------------------------------------===// @@ -1149,6 +1249,12 @@ Sema::CreateGenericSelectionExpr(SourceLocation KeyLoc, TypeSourceInfo **Types, Expr **Exprs, unsigned NumAssocs) { + if (ControllingExpr->getType()->isPlaceholderType()) { + ExprResult result = CheckPlaceholderExpr(ControllingExpr); + if (result.isInvalid()) return ExprError(); + ControllingExpr = result.take(); + } + bool TypeErrorFound = false, IsResultDependent = ControllingExpr->isTypeDependent(), ContainsUnexpandedParameterPack @@ -1401,7 +1507,7 @@ Sema::BuildDeclRefExpr(ValueDecl *D, QualType Ty, ExprValueKind VK, ExprResult Sema::BuildDeclRefExpr(ValueDecl *D, QualType Ty, ExprValueKind VK, const DeclarationNameInfo &NameInfo, - const CXXScopeSpec *SS) { + const CXXScopeSpec *SS, NamedDecl *FoundD) { if (getLangOpts().CUDA) if (const FunctionDecl *Caller = dyn_cast<FunctionDecl>(CurContext)) if (const FunctionDecl *Callee = dyn_cast<FunctionDecl>(D)) { @@ -1425,7 +1531,7 @@ Sema::BuildDeclRefExpr(ValueDecl *D, QualType Ty, ExprValueKind VK, : NestedNameSpecifierLoc(), SourceLocation(), D, refersToEnclosingScope, - NameInfo, Ty, VK); + NameInfo, Ty, VK, FoundD); MarkDeclRefReferenced(E); @@ -1533,9 +1639,10 @@ bool Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R, UnresolvedLookupExpr *ULE = cast<UnresolvedLookupExpr>( CallsUndergoingInstantiation.back()->getCallee()); - CXXMethodDecl *DepMethod; - if (CurMethod->getTemplatedKind() == + if (CurMethod->isDependentContext()) + DepMethod = CurMethod; + else if (CurMethod->getTemplatedKind() == FunctionDecl::TK_FunctionTemplateSpecialization) DepMethod = cast<CXXMethodDecl>(CurMethod->getPrimaryTemplate()-> getInstantiatedFromMemberTemplate()->getTemplatedDecl()); @@ -1642,9 +1749,13 @@ bool Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R, << SS.getRange() << FixItHint::CreateReplacement(Corrected.getCorrectionRange(), CorrectedStr); - if (ND) - Diag(ND->getLocation(), diag::note_previous_decl) - << CorrectedQuotedStr; + + unsigned diag = isa<ImplicitParamDecl>(ND) + ? diag::note_implicit_param_decl + : diag::note_previous_decl; + + Diag(ND->getLocation(), diag) + << CorrectedQuotedStr; // Tell the callee to try to recover. return false; @@ -1946,6 +2057,10 @@ Sema::LookupInObjCMethod(LookupResult &Lookup, Scope *S, IdentifierInfo *II, bool AllowBuiltinCreation) { SourceLocation Loc = Lookup.getNameLoc(); ObjCMethodDecl *CurMethod = getCurMethodDecl(); + + // Check for error condition which is already reported. + if (!CurMethod) + return ExprError(); // There are two cases to handle here. 1) scoped lookup could have failed, // in which case we should look for an ivar. 2) scoped lookup could have @@ -2009,14 +2124,15 @@ Sema::LookupInObjCMethod(LookupResult &Lookup, Scope *S, if (SelfExpr.isInvalid()) return ExprError(); - MarkAnyDeclReferenced(Loc, IV); + MarkAnyDeclReferenced(Loc, IV, true); ObjCMethodFamily MF = CurMethod->getMethodFamily(); - if (MF != OMF_init && MF != OMF_dealloc && MF != OMF_finalize) + if (MF != OMF_init && MF != OMF_dealloc && MF != OMF_finalize && + !IvarBacksCurrentMethodAccessor(IFace, CurMethod, IV)) Diag(Loc, diag::warn_direct_ivar_access) << IV->getDeclName(); ObjCIvarRefExpr *Result = new (Context) ObjCIvarRefExpr(IV, IV->getType(), - Loc, + Loc, IV->getLocation(), SelfExpr.take(), true, true); @@ -2321,8 +2437,8 @@ Sema::BuildDeclarationNameExpr(const CXXScopeSpec &SS, // If this is a single, fully-resolved result and we don't need ADL, // just build an ordinary singleton decl ref. if (!NeedsADL && R.isSingleResult() && !R.getAsSingle<FunctionTemplateDecl>()) - return BuildDeclarationNameExpr(SS, R.getLookupNameInfo(), - R.getFoundDecl()); + return BuildDeclarationNameExpr(SS, R.getLookupNameInfo(), R.getFoundDecl(), + R.getRepresentativeDecl()); // We only need to check the declaration if there's exactly one // result, because in the overloaded case the results can only be @@ -2350,7 +2466,7 @@ Sema::BuildDeclarationNameExpr(const CXXScopeSpec &SS, ExprResult Sema::BuildDeclarationNameExpr(const CXXScopeSpec &SS, const DeclarationNameInfo &NameInfo, - NamedDecl *D) { + NamedDecl *D, NamedDecl *FoundD) { assert(D && "Cannot refer to a NULL declaration"); assert(!isa<FunctionTemplateDecl>(D) && "Cannot refer unambiguously to a function template"); @@ -2546,7 +2662,7 @@ Sema::BuildDeclarationNameExpr(const CXXScopeSpec &SS, break; } - return BuildDeclRefExpr(VD, type, valueKind, NameInfo, &SS); + return BuildDeclRefExpr(VD, type, valueKind, NameInfo, &SS, FoundD); } } @@ -2565,8 +2681,14 @@ ExprResult Sema::ActOnPredefinedExpr(SourceLocation Loc, tok::TokenKind Kind) { // string. Decl *currentDecl = getCurFunctionOrMethodDecl(); - if (!currentDecl && getCurBlock()) - currentDecl = getCurBlock()->TheDecl; + // Blocks and lambdas can occur at global scope. Don't emit a warning. + if (!currentDecl) { + if (const BlockScopeInfo *BSI = getCurBlock()) + currentDecl = BSI->TheDecl; + else if (const LambdaScopeInfo *LSI = getCurLambda()) + currentDecl = LSI->CallOperator; + } + if (!currentDecl) { Diag(Loc, diag::ext_predef_outside_function); currentDecl = Context.getTranslationUnitDecl(); @@ -2764,7 +2886,7 @@ ExprResult Sema::ActOnNumericConstant(const Token &Tok, Scope *UDLScope) { SourceLocation TokLoc = Tok.getLocation(); unsigned Length = Literal.getUDSuffixOffset(); QualType StrTy = Context.getConstantArrayType( - Context.CharTy, llvm::APInt(32, Length + 1), + Context.CharTy.withConst(), llvm::APInt(32, Length + 1), ArrayType::Normal, 0); Expr *Lit = StringLiteral::Create( Context, StringRef(TokSpelling.data(), Length), StringLiteral::Ascii, @@ -2825,7 +2947,7 @@ ExprResult Sema::ActOnNumericConstant(const Token &Tok, Scope *UDLScope) { if (!getLangOpts().C99 && Literal.isLongLong) { if (getLangOpts().CPlusPlus) Diag(Tok.getLocation(), - getLangOpts().CPlusPlus0x ? + getLangOpts().CPlusPlus11 ? diag::warn_cxx98_compat_longlong : diag::ext_cxx11_longlong); else Diag(Tok.getLocation(), diag::ext_c99_longlong); @@ -2835,7 +2957,10 @@ ExprResult Sema::ActOnNumericConstant(const Token &Tok, Scope *UDLScope) { unsigned MaxWidth = Context.getTargetInfo().getIntMaxTWidth(); // The microsoft literal suffix extensions support 128-bit literals, which // may be wider than [u]intmax_t. - if (Literal.isMicrosoftInteger && MaxWidth < 128) + // FIXME: Actually, they don't. We seem to have accidentally invented the + // i128 suffix. + if (Literal.isMicrosoftInteger && MaxWidth < 128 && + PP.getTargetInfo().hasInt128Type()) MaxWidth = 128; llvm::APInt ResultVal(MaxWidth, 0); @@ -2905,7 +3030,8 @@ ExprResult Sema::ActOnNumericConstant(const Token &Tok, Scope *UDLScope) { // If it doesn't fit in unsigned long long, and we're using Microsoft // extensions, then its a 128-bit integer literal. - if (Ty.isNull() && Literal.isMicrosoftInteger) { + if (Ty.isNull() && Literal.isMicrosoftInteger && + PP.getTargetInfo().hasInt128Type()) { if (Literal.isUnsigned) Ty = Context.UnsignedInt128Ty; else @@ -2963,16 +3089,17 @@ static bool CheckExtensionTraitOperandType(Sema &S, QualType T, SourceRange ArgRange, UnaryExprOrTypeTrait TraitKind) { // C99 6.5.3.4p1: - if (T->isFunctionType()) { - // alignof(function) is allowed as an extension. - if (TraitKind == UETT_SizeOf) - S.Diag(Loc, diag::ext_sizeof_function_type) << ArgRange; + if (T->isFunctionType() && + (TraitKind == UETT_SizeOf || TraitKind == UETT_AlignOf)) { + // sizeof(function)/alignof(function) is allowed as an extension. + S.Diag(Loc, diag::ext_sizeof_alignof_function_type) + << TraitKind << ArgRange; return false; } // Allow sizeof(void)/alignof(void) as an extension. if (T->isVoidType()) { - S.Diag(Loc, diag::ext_sizeof_void_type) << TraitKind << ArgRange; + S.Diag(Loc, diag::ext_sizeof_alignof_void_type) << TraitKind << ArgRange; return false; } @@ -2995,6 +3122,24 @@ static bool CheckObjCTraitOperandConstraints(Sema &S, QualType T, return false; } +/// \brief Check whether E is a pointer from a decayed array type (the decayed +/// pointer type is equal to T) and emit a warning if it is. +static void warnOnSizeofOnArrayDecay(Sema &S, SourceLocation Loc, QualType T, + Expr *E) { + // Don't warn if the operation changed the type. + if (T != E->getType()) + return; + + // Now look for array decays. + ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(E); + if (!ICE || ICE->getCastKind() != CK_ArrayToPointerDecay) + return; + + S.Diag(Loc, diag::warn_sizeof_array_decay) << ICE->getSourceRange() + << ICE->getType() + << ICE->getSubExpr()->getType(); +} + /// \brief Check the constrains on expression operands to unary type expression /// and type traits. /// @@ -3048,6 +3193,16 @@ bool Sema::CheckUnaryExprOrTypeTraitOperand(Expr *E, } } } + + // Warn on "sizeof(array op x)" and "sizeof(x op array)", where the array + // decays into a pointer and returns an unintended result. This is most + // likely a typo for "sizeof(array) op x". + if (BinaryOperator *BO = dyn_cast<BinaryOperator>(E->IgnoreParens())) { + warnOnSizeofOnArrayDecay(*this, BO->getOperatorLoc(), BO->getType(), + BO->getLHS()); + warnOnSizeofOnArrayDecay(*this, BO->getOperatorLoc(), BO->getType(), + BO->getRHS()); + } } return false; @@ -3189,7 +3344,7 @@ Sema::CreateUnaryExprOrTypeTraitExpr(Expr *E, SourceLocation OpLoc, return ExprError(); if (ExprKind == UETT_SizeOf && E->getType()->isVariableArrayType()) { - PE = TranformToPotentiallyEvaluated(E); + PE = TransformToPotentiallyEvaluated(E); if (PE.isInvalid()) return ExprError(); E = PE.take(); } @@ -3292,33 +3447,56 @@ static bool checkArithmeticOnObjCPointer(Sema &S, } ExprResult -Sema::ActOnArraySubscriptExpr(Scope *S, Expr *Base, SourceLocation LLoc, - Expr *Idx, SourceLocation RLoc) { +Sema::ActOnArraySubscriptExpr(Scope *S, Expr *base, SourceLocation lbLoc, + Expr *idx, SourceLocation rbLoc) { // Since this might be a postfix expression, get rid of ParenListExprs. - ExprResult Result = MaybeConvertParenListExprToParenExpr(S, Base); - if (Result.isInvalid()) return ExprError(); - Base = Result.take(); + if (isa<ParenListExpr>(base)) { + ExprResult result = MaybeConvertParenListExprToParenExpr(S, base); + if (result.isInvalid()) return ExprError(); + base = result.take(); + } - Expr *LHSExp = Base, *RHSExp = Idx; + // Handle any non-overload placeholder types in the base and index + // expressions. We can't handle overloads here because the other + // operand might be an overloadable type, in which case the overload + // resolution for the operator overload should get the first crack + // at the overload. + if (base->getType()->isNonOverloadPlaceholderType()) { + ExprResult result = CheckPlaceholderExpr(base); + if (result.isInvalid()) return ExprError(); + base = result.take(); + } + if (idx->getType()->isNonOverloadPlaceholderType()) { + ExprResult result = CheckPlaceholderExpr(idx); + if (result.isInvalid()) return ExprError(); + idx = result.take(); + } + // Build an unanalyzed expression if either operand is type-dependent. if (getLangOpts().CPlusPlus && - (LHSExp->isTypeDependent() || RHSExp->isTypeDependent())) { - return Owned(new (Context) ArraySubscriptExpr(LHSExp, RHSExp, + (base->isTypeDependent() || idx->isTypeDependent())) { + return Owned(new (Context) ArraySubscriptExpr(base, idx, Context.DependentTy, VK_LValue, OK_Ordinary, - RLoc)); + rbLoc)); } + // Use C++ overloaded-operator rules if either operand has record + // type. The spec says to do this if either type is *overloadable*, + // but enum types can't declare subscript operators or conversion + // operators, so there's nothing interesting for overload resolution + // to do if there aren't any record types involved. + // + // ObjC pointers have their own subscripting logic that is not tied + // to overload resolution and so should not take this path. if (getLangOpts().CPlusPlus && - (LHSExp->getType()->isRecordType() || - LHSExp->getType()->isEnumeralType() || - RHSExp->getType()->isRecordType() || - RHSExp->getType()->isEnumeralType()) && - !LHSExp->getType()->isObjCObjectPointerType()) { - return CreateOverloadedArraySubscriptExpr(LLoc, RLoc, Base, Idx); + (base->getType()->isRecordType() || + (!base->getType()->isObjCObjectPointerType() && + idx->getType()->isRecordType()))) { + return CreateOverloadedArraySubscriptExpr(lbLoc, rbLoc, base, idx); } - return CreateBuiltinArraySubscriptExpr(Base, LLoc, Idx, RLoc); + return CreateBuiltinArraySubscriptExpr(base, lbLoc, idx, rbLoc); } ExprResult @@ -3525,7 +3703,7 @@ ExprResult Sema::BuildCXXDefaultArgExpr(SourceLocation CallLoc, return ExprError(); Expr *Arg = Result.takeAs<Expr>(); - CheckImplicitConversions(Arg, Param->getOuterLocStart()); + CheckCompletedExpr(Arg, Param->getOuterLocStart()); // Build the default argument expression. return Owned(CXXDefaultArgExpr::Create(Context, CallLoc, Param, Arg)); } @@ -3687,7 +3865,8 @@ bool Sema::GatherArgumentsForCall(SourceLocation CallLoc, Expr **Args, unsigned NumArgs, SmallVector<Expr *, 8> &AllArgs, VariadicCallType CallType, - bool AllowExplicit) { + bool AllowExplicit, + bool IsListInitialization) { unsigned NumArgsInProto = Proto->getNumArgs(); unsigned NumArgsToCheck = NumArgs; bool Invalid = false; @@ -3720,20 +3899,21 @@ bool Sema::GatherArgumentsForCall(SourceLocation CallLoc, (!Param || !Param->hasAttr<CFConsumedAttr>())) Arg = stripARCUnbridgedCast(Arg); - InitializedEntity Entity = - Param? InitializedEntity::InitializeParameter(Context, Param) - : InitializedEntity::InitializeParameter(Context, ProtoArgType, - Proto->isArgConsumed(i)); + InitializedEntity Entity = Param ? + InitializedEntity::InitializeParameter(Context, Param, ProtoArgType) + : InitializedEntity::InitializeParameter(Context, ProtoArgType, + Proto->isArgConsumed(i)); ExprResult ArgE = PerformCopyInitialization(Entity, SourceLocation(), Owned(Arg), - /*TopLevelOfInitList=*/false, + IsListInitialization, AllowExplicit); if (ArgE.isInvalid()) return true; Arg = ArgE.takeAs<Expr>(); } else { + assert(FDecl && "can't use default arguments without a known callee"); Param = FDecl->getParamDecl(i); ExprResult ArgExpr = @@ -3762,11 +3942,8 @@ bool Sema::GatherArgumentsForCall(SourceLocation CallLoc, if (Proto->getResultType() == Context.UnknownAnyTy && FDecl && FDecl->isExternC()) { for (unsigned i = ArgIx; i != NumArgs; ++i) { - ExprResult arg; - if (isa<ExplicitCastExpr>(Args[i]->IgnoreParens())) - arg = DefaultFunctionArrayLvalueConversion(Args[i]); - else - arg = DefaultVariadicArgumentPromotion(Args[i], CallType, FDecl); + QualType paramType; // ignored + ExprResult arg = checkUnknownAnyArg(CallLoc, Args[i], paramType); Invalid |= arg.isInvalid(); AllArgs.push_back(arg.take()); } @@ -3790,9 +3967,9 @@ bool Sema::GatherArgumentsForCall(SourceLocation CallLoc, static void DiagnoseCalleeStaticArrayParam(Sema &S, ParmVarDecl *PVD) { TypeLoc TL = PVD->getTypeSourceInfo()->getTypeLoc(); - if (ArrayTypeLoc *ATL = dyn_cast<ArrayTypeLoc>(&TL)) + if (ArrayTypeLoc ATL = TL.getAs<ArrayTypeLoc>()) S.Diag(PVD->getLocation(), diag::note_callee_static_array) - << ATL->getLocalSourceRange(); + << ATL.getLocalSourceRange(); } /// CheckStaticArrayArgument - If the given argument corresponds to a static @@ -4593,10 +4770,15 @@ ExprResult Sema::BuildVectorLiteral(SourceLocation LParenLoc, Expr **exprs; unsigned numExprs; Expr *subExpr; + SourceLocation LiteralLParenLoc, LiteralRParenLoc; if (ParenListExpr *PE = dyn_cast<ParenListExpr>(E)) { + LiteralLParenLoc = PE->getLParenLoc(); + LiteralRParenLoc = PE->getRParenLoc(); exprs = PE->getExprs(); numExprs = PE->getNumExprs(); - } else { + } else { // isa<ParenExpr> by assertion at function entrance + LiteralLParenLoc = cast<ParenExpr>(E)->getLParen(); + LiteralRParenLoc = cast<ParenExpr>(E)->getRParen(); subExpr = cast<ParenExpr>(E)->getSubExpr(); exprs = &subExpr; numExprs = 1; @@ -4653,8 +4835,8 @@ ExprResult Sema::BuildVectorLiteral(SourceLocation LParenLoc, } // FIXME: This means that pretty-printing the final AST will produce curly // braces instead of the original commas. - InitListExpr *initE = new (Context) InitListExpr(Context, LParenLoc, - initExprs, RParenLoc); + InitListExpr *initE = new (Context) InitListExpr(Context, LiteralLParenLoc, + initExprs, LiteralRParenLoc); initE->setType(Ty); return BuildCompoundLiteralExpr(LParenLoc, TInfo, RParenLoc, initE); } @@ -4681,7 +4863,6 @@ Sema::MaybeConvertParenListExprToParenExpr(Scope *S, Expr *OrigExpr) { ExprResult Sema::ActOnParenListExpr(SourceLocation L, SourceLocation R, MultiExprArg Val) { - assert(Val.data() != 0 && "ActOnParenOrParenListExpr() missing expr list"); Expr *expr = new (Context) ParenListExpr(Context, L, Val, R); return Owned(expr); } @@ -4720,7 +4901,7 @@ bool Sema::DiagnoseConditionalForNull(Expr *LHSExpr, Expr *RHSExpr, return false; } - int DiagType = (NullKind == Expr::NPCK_CXX0X_nullptr); + int DiagType = (NullKind == Expr::NPCK_CXX11_nullptr); Diag(QuestionLoc, diag::err_typecheck_cond_incompatible_operands_null) << NonPointerExpr->getType() << DiagType << NonPointerExpr->getSourceRange(); @@ -4734,7 +4915,7 @@ static bool checkCondition(Sema &S, Expr *Cond) { // C99 6.5.15p2 if (CondTy->isScalarType()) return false; - // OpenCL: Sec 6.3.i says the condition is allowed to be a vector or scalar. + // OpenCL v1.1 s6.3.i says the condition is allowed to be a vector or scalar. if (S.getLangOpts().OpenCL && CondTy->isVectorType()) return false; @@ -4995,9 +5176,9 @@ QualType Sema::CheckConditionalOperands(ExprResult &Cond, ExprResult &LHS, if (LHSTy->isVectorType() || RHSTy->isVectorType()) return CheckVectorOperands(LHS, RHS, QuestionLoc, /*isCompAssign*/false); - // OpenCL: If the condition is a vector, and both operands are scalar, + // If the condition is a vector, and both operands are scalar, // attempt to implicity convert them to the vector type to act like the - // built in select. + // built in select. (OpenCL v1.1 s6.3.i) if (getLangOpts().OpenCL && CondTy->isVectorType()) if (checkConditionalConvertScalarsToVectors(*this, LHS, RHS, CondTy)) return QualType(); @@ -5264,7 +5445,8 @@ static bool IsArithmeticBinaryExpr(Expr *E, BinaryOperatorKind *Opcode, // Make sure this is really a binary operator that is safe to pass into // BinaryOperator::getOverloadedOpcode(), e.g. it's not a subscript op. OverloadedOperatorKind OO = Call->getOperator(); - if (OO < OO_Plus || OO > OO_Arrow) + if (OO < OO_Plus || OO > OO_Arrow || + OO == OO_PlusPlus || OO == OO_MinusMinus) return false; BinaryOperatorKind OpKind = BinaryOperator::getOverloadedOpcode(OO); @@ -5625,7 +5807,6 @@ Sema::CheckAssignmentConstraints(QualType LHSType, ExprResult &RHS, LHSType = Context.getCanonicalType(LHSType).getUnqualifiedType(); RHSType = Context.getCanonicalType(RHSType).getUnqualifiedType(); - // Common case: no conversion required. if (LHSType == RHSType) { Kind = CK_NoOp; @@ -6570,6 +6751,11 @@ static bool isScopedEnumerationType(QualType T) { static void DiagnoseBadShiftValues(Sema& S, ExprResult &LHS, ExprResult &RHS, SourceLocation Loc, unsigned Opc, QualType LHSType) { + // OpenCL 6.3j: shift values are effectively % word size of LHS (more defined), + // so skip remaining warnings as we don't want to modify values within Sema. + if (S.getLangOpts().OpenCL) + return; + llvm::APSInt Right; // Check right/shifter operand if (RHS.get()->isValueDependent() || @@ -6689,10 +6875,10 @@ static bool IsWithinTemplateSpecialization(Decl *D) { } /// If two different enums are compared, raise a warning. -static void checkEnumComparison(Sema &S, SourceLocation Loc, ExprResult &LHS, - ExprResult &RHS) { - QualType LHSStrippedType = LHS.get()->IgnoreParenImpCasts()->getType(); - QualType RHSStrippedType = RHS.get()->IgnoreParenImpCasts()->getType(); +static void checkEnumComparison(Sema &S, SourceLocation Loc, Expr *LHS, + Expr *RHS) { + QualType LHSStrippedType = LHS->IgnoreParenImpCasts()->getType(); + QualType RHSStrippedType = RHS->IgnoreParenImpCasts()->getType(); const EnumType *LHSEnumType = LHSStrippedType->getAs<EnumType>(); if (!LHSEnumType) @@ -6712,7 +6898,7 @@ static void checkEnumComparison(Sema &S, SourceLocation Loc, ExprResult &LHS, S.Diag(Loc, diag::warn_comparison_of_mixed_enum_types) << LHSStrippedType << RHSStrippedType - << LHS.get()->getSourceRange() << RHS.get()->getSourceRange(); + << LHS->getSourceRange() << RHS->getSourceRange(); } /// \brief Diagnose bad pointer comparisons. @@ -6796,18 +6982,18 @@ static bool isObjCObjectLiteral(ExprResult &E) { } static bool hasIsEqualMethod(Sema &S, const Expr *LHS, const Expr *RHS) { - // Get the LHS object's interface type. - QualType Type = LHS->getType(); - QualType InterfaceType; - if (const ObjCObjectPointerType *PTy = Type->getAs<ObjCObjectPointerType>()) { - InterfaceType = PTy->getPointeeType(); - if (const ObjCObjectType *iQFaceTy = - InterfaceType->getAsObjCQualifiedInterfaceType()) - InterfaceType = iQFaceTy->getBaseType(); - } else { - // If this is not actually an Objective-C object, bail out. + const ObjCObjectPointerType *Type = + LHS->getType()->getAs<ObjCObjectPointerType>(); + + // If this is not actually an Objective-C object, bail out. + if (!Type) return false; - } + + // Get the LHS object's interface type. + QualType InterfaceType = Type->getPointeeType(); + if (const ObjCObjectType *iQFaceTy = + InterfaceType->getAsObjCQualifiedInterfaceType()) + InterfaceType = iQFaceTy->getBaseType(); // If the RHS isn't an Objective-C object, bail out. if (!RHS->getType()->isObjCObjectPointerType()) @@ -6826,8 +7012,7 @@ static bool hasIsEqualMethod(Sema &S, const Expr *LHS, const Expr *RHS) { /*warn=*/false); } else { // Check protocols. - Method = S.LookupMethodInQualifiedType(IsEqualSel, - cast<ObjCObjectPointerType>(Type), + Method = S.LookupMethodInQualifiedType(IsEqualSel, Type, /*instance=*/true); } } @@ -6846,6 +7031,48 @@ static bool hasIsEqualMethod(Sema &S, const Expr *LHS, const Expr *RHS) { return true; } +Sema::ObjCLiteralKind Sema::CheckLiteralKind(Expr *FromE) { + FromE = FromE->IgnoreParenImpCasts(); + switch (FromE->getStmtClass()) { + default: + break; + case Stmt::ObjCStringLiteralClass: + // "string literal" + return LK_String; + case Stmt::ObjCArrayLiteralClass: + // "array literal" + return LK_Array; + case Stmt::ObjCDictionaryLiteralClass: + // "dictionary literal" + return LK_Dictionary; + case Stmt::BlockExprClass: + return LK_Block; + case Stmt::ObjCBoxedExprClass: { + Expr *Inner = cast<ObjCBoxedExpr>(FromE)->getSubExpr()->IgnoreParens(); + switch (Inner->getStmtClass()) { + case Stmt::IntegerLiteralClass: + case Stmt::FloatingLiteralClass: + case Stmt::CharacterLiteralClass: + case Stmt::ObjCBoolLiteralExprClass: + case Stmt::CXXBoolLiteralExprClass: + // "numeric literal" + return LK_Numeric; + case Stmt::ImplicitCastExprClass: { + CastKind CK = cast<CastExpr>(Inner)->getCastKind(); + // Boolean literals can be represented by implicit casts. + if (CK == CK_IntegralToBoolean || CK == CK_IntegralCast) + return LK_Numeric; + break; + } + default: + break; + } + return LK_Boxed; + } + } + return LK_None; +} + static void diagnoseObjCLiteralComparison(Sema &S, SourceLocation Loc, ExprResult &LHS, ExprResult &RHS, BinaryOperator::Opcode Opc){ @@ -6866,61 +7093,15 @@ static void diagnoseObjCLiteralComparison(Sema &S, SourceLocation Loc, return; // This should be kept in sync with warn_objc_literal_comparison. - // LK_String should always be last, since it has its own warning flag. - enum { - LK_Array, - LK_Dictionary, - LK_Numeric, - LK_Boxed, - LK_String - } LiteralKind; - - Literal = Literal->IgnoreParenImpCasts(); - switch (Literal->getStmtClass()) { - case Stmt::ObjCStringLiteralClass: - // "string literal" - LiteralKind = LK_String; - break; - case Stmt::ObjCArrayLiteralClass: - // "array literal" - LiteralKind = LK_Array; - break; - case Stmt::ObjCDictionaryLiteralClass: - // "dictionary literal" - LiteralKind = LK_Dictionary; - break; - case Stmt::ObjCBoxedExprClass: { - Expr *Inner = cast<ObjCBoxedExpr>(Literal)->getSubExpr(); - switch (Inner->getStmtClass()) { - case Stmt::IntegerLiteralClass: - case Stmt::FloatingLiteralClass: - case Stmt::CharacterLiteralClass: - case Stmt::ObjCBoolLiteralExprClass: - case Stmt::CXXBoolLiteralExprClass: - // "numeric literal" - LiteralKind = LK_Numeric; - break; - case Stmt::ImplicitCastExprClass: { - CastKind CK = cast<CastExpr>(Inner)->getCastKind(); - // Boolean literals can be represented by implicit casts. - if (CK == CK_IntegralToBoolean || CK == CK_IntegralCast) { - LiteralKind = LK_Numeric; - break; - } - // FALLTHROUGH - } - default: - // "boxed expression" - LiteralKind = LK_Boxed; - break; - } - break; - } - default: + // LK_String should always be after the other literals, since it has its own + // warning flag. + Sema::ObjCLiteralKind LiteralKind = S.CheckLiteralKind(Literal); + assert(LiteralKind != Sema::LK_Block); + if (LiteralKind == Sema::LK_None) { llvm_unreachable("Unknown Objective-C object literal kind"); } - if (LiteralKind == LK_String) + if (LiteralKind == Sema::LK_String) S.Diag(Loc, diag::warn_objc_string_literal_comparison) << Literal->getSourceRange(); else @@ -6931,11 +7112,12 @@ static void diagnoseObjCLiteralComparison(Sema &S, SourceLocation Loc, hasIsEqualMethod(S, LHS.get(), RHS.get())) { SourceLocation Start = LHS.get()->getLocStart(); SourceLocation End = S.PP.getLocForEndOfToken(RHS.get()->getLocEnd()); - SourceRange OpRange(Loc, S.PP.getLocForEndOfToken(Loc)); + CharSourceRange OpRange = + CharSourceRange::getCharRange(Loc, S.PP.getLocForEndOfToken(Loc)); S.Diag(Loc, diag::note_objc_literal_comparison_isequal) << FixItHint::CreateInsertion(Start, Opc == BO_EQ ? "[" : "![") - << FixItHint::CreateReplacement(OpRange, "isEqual:") + << FixItHint::CreateReplacement(OpRange, " isEqual:") << FixItHint::CreateInsertion(End, "]"); } } @@ -6959,7 +7141,7 @@ QualType Sema::CheckCompareOperands(ExprResult &LHS, ExprResult &RHS, Expr *LHSStripped = LHS.get()->IgnoreParenImpCasts(); Expr *RHSStripped = RHS.get()->IgnoreParenImpCasts(); - checkEnumComparison(*this, Loc, LHS, RHS); + checkEnumComparison(*this, Loc, LHS.get(), RHS.get()); if (!LHSType->hasFloatingRepresentation() && !(LHSType->isBlockPointerType() && IsRelational) && @@ -7109,7 +7291,7 @@ QualType Sema::CheckCompareOperands(ExprResult &LHS, ExprResult &RHS, if ((LCanPointeeTy->isFunctionType() || RCanPointeeTy->isFunctionType()) && !LHSIsNull && !RHSIsNull) { diagnoseFunctionPointerToVoidComparison( - *this, Loc, LHS, RHS, /*isError*/ isSFINAEContext()); + *this, Loc, LHS, RHS, /*isError*/ (bool)isSFINAEContext()); if (isSFINAEContext()) return QualType(); @@ -7396,7 +7578,10 @@ QualType Sema::CheckVectorLogicalOperands(ExprResult &LHS, ExprResult &RHS, // Ensure that either both operands are of the same vector type, or // one operand is of a vector type and the other is of its element type. QualType vType = CheckVectorOperands(LHS, RHS, Loc, false); - if (vType.isNull() || vType->isFloatingType()) + if (vType.isNull()) + return InvalidOperands(Loc, LHS, RHS); + if (getLangOpts().OpenCL && getLangOpts().OpenCLVersion < 120 && + vType->hasFloatingRepresentation()) return InvalidOperands(Loc, LHS, RHS); return GetSignedVectorType(LHS.get()->getType()); @@ -7472,8 +7657,17 @@ inline QualType Sema::CheckLogicalOperands( // C99 6.5.[13,14] RHS.get()->getLocEnd())); } } - + if (!Context.getLangOpts().CPlusPlus) { + // OpenCL v1.1 s6.3.g: The logical operators and (&&), or (||) do + // not operate on the built-in scalar and vector float types. + if (Context.getLangOpts().OpenCL && + Context.getLangOpts().OpenCLVersion < 120) { + if (LHS.get()->getType()->isFloatingType() || + RHS.get()->getType()->isFloatingType()) + return InvalidOperands(Loc, LHS, RHS); + } + LHS = UsualUnaryConversions(LHS.take()); if (LHS.isInvalid()) return QualType(); @@ -7999,7 +8193,9 @@ static QualType CheckAddressOfOperand(Sema &S, ExprResult &OrigOp, if (const BuiltinType *PTy = OrigOp.get()->getType()->getAsPlaceholderType()){ if (PTy->getKind() == BuiltinType::Overload) { if (!isa<OverloadExpr>(OrigOp.get()->IgnoreParens())) { - S.Diag(OpLoc, diag::err_typecheck_invalid_lvalue_addrof) + assert(cast<UnaryOperator>(OrigOp.get()->IgnoreParens())->getOpcode() + == UO_AddrOf); + S.Diag(OpLoc, diag::err_typecheck_invalid_lvalue_addrof_addrof_function) << OrigOp.get()->getSourceRange(); return QualType(); } @@ -8043,10 +8239,10 @@ static QualType CheckAddressOfOperand(Sema &S, ExprResult &OrigOp, Expr::LValueClassification lval = op->ClassifyLValue(S.Context); unsigned AddressOfError = AO_No_Error; - if (lval == Expr::LV_ClassTemporary) { - bool sfinae = S.isSFINAEContext(); - S.Diag(OpLoc, sfinae ? diag::err_typecheck_addrof_class_temporary - : diag::ext_typecheck_addrof_class_temporary) + if (lval == Expr::LV_ClassTemporary || lval == Expr::LV_ArrayTemporary) { + bool sfinae = (bool)S.isSFINAEContext(); + S.Diag(OpLoc, S.isSFINAEContext() ? diag::err_typecheck_addrof_temporary + : diag::ext_typecheck_addrof_temporary) << op->getType() << op->getSourceRange(); if (sfinae) return QualType(); @@ -8094,9 +8290,8 @@ static QualType CheckAddressOfOperand(Sema &S, ExprResult &OrigOp, if (isa<PseudoObjectExpr>(op)) { AddressOfError = AO_Property_Expansion; } else { - // FIXME: emit more specific diag... S.Diag(OpLoc, diag::err_typecheck_invalid_lvalue_addrof) - << op->getSourceRange(); + << op->getType() << op->getSourceRange(); return QualType(); } } @@ -8312,7 +8507,7 @@ static void DiagnoseSelfAssignment(Sema &S, Expr *LHSExpr, Expr *RHSExpr, ExprResult Sema::CreateBuiltinBinOp(SourceLocation OpLoc, BinaryOperatorKind Opc, Expr *LHSExpr, Expr *RHSExpr) { - if (getLangOpts().CPlusPlus0x && isa<InitListExpr>(RHSExpr)) { + if (getLangOpts().CPlusPlus11 && isa<InitListExpr>(RHSExpr)) { // The syntax only allows initializer lists on the RHS of assignment, // so we don't need to worry about accepting invalid code for // non-assignment operators. @@ -8445,6 +8640,24 @@ ExprResult Sema::CreateBuiltinBinOp(SourceLocation OpLoc, CheckArrayAccess(LHS.get()); CheckArrayAccess(RHS.get()); + if (const ObjCIsaExpr *OISA = dyn_cast<ObjCIsaExpr>(LHS.get()->IgnoreParenCasts())) { + NamedDecl *ObjectSetClass = LookupSingleName(TUScope, + &Context.Idents.get("object_setClass"), + SourceLocation(), LookupOrdinaryName); + if (ObjectSetClass && isa<ObjCIsaExpr>(LHS.get())) { + SourceLocation RHSLocEnd = PP.getLocForEndOfToken(RHS.get()->getLocEnd()); + Diag(LHS.get()->getExprLoc(), diag::warn_objc_isa_assign) << + FixItHint::CreateInsertion(LHS.get()->getLocStart(), "object_setClass(") << + FixItHint::CreateReplacement(SourceRange(OISA->getOpLoc(), OpLoc), ",") << + FixItHint::CreateInsertion(RHSLocEnd, ")"); + } + else + Diag(LHS.get()->getExprLoc(), diag::warn_objc_isa_assign); + } + else if (const ObjCIvarRefExpr *OIRE = + dyn_cast<ObjCIvarRefExpr>(LHS.get()->IgnoreParenCasts())) + DiagnoseDirectIsaAccess(*this, OIRE, OpLoc, RHS.get()); + if (CompResultTy.isNull()) return Owned(new (Context) BinaryOperator(LHS.take(), RHS.take(), Opc, ResultTy, VK, OK, OpLoc, @@ -8467,46 +8680,38 @@ ExprResult Sema::CreateBuiltinBinOp(SourceLocation OpLoc, static void DiagnoseBitwisePrecedence(Sema &Self, BinaryOperatorKind Opc, SourceLocation OpLoc, Expr *LHSExpr, Expr *RHSExpr) { - typedef BinaryOperator BinOp; - BinOp::Opcode LHSopc = static_cast<BinOp::Opcode>(-1), - RHSopc = static_cast<BinOp::Opcode>(-1); - if (BinOp *BO = dyn_cast<BinOp>(LHSExpr)) - LHSopc = BO->getOpcode(); - if (BinOp *BO = dyn_cast<BinOp>(RHSExpr)) - RHSopc = BO->getOpcode(); - - // Subs are not binary operators. - if (LHSopc == -1 && RHSopc == -1) + BinaryOperator *LHSBO = dyn_cast<BinaryOperator>(LHSExpr); + BinaryOperator *RHSBO = dyn_cast<BinaryOperator>(RHSExpr); + + // Check that one of the sides is a comparison operator. + bool isLeftComp = LHSBO && LHSBO->isComparisonOp(); + bool isRightComp = RHSBO && RHSBO->isComparisonOp(); + if (!isLeftComp && !isRightComp) return; // Bitwise operations are sometimes used as eager logical ops. // Don't diagnose this. - if ((BinOp::isComparisonOp(LHSopc) || BinOp::isBitwiseOp(LHSopc)) && - (BinOp::isComparisonOp(RHSopc) || BinOp::isBitwiseOp(RHSopc))) + bool isLeftBitwise = LHSBO && LHSBO->isBitwiseOp(); + bool isRightBitwise = RHSBO && RHSBO->isBitwiseOp(); + if ((isLeftComp || isLeftBitwise) && (isRightComp || isRightBitwise)) return; - bool isLeftComp = BinOp::isComparisonOp(LHSopc); - bool isRightComp = BinOp::isComparisonOp(RHSopc); - if (!isLeftComp && !isRightComp) return; - SourceRange DiagRange = isLeftComp ? SourceRange(LHSExpr->getLocStart(), OpLoc) : SourceRange(OpLoc, RHSExpr->getLocEnd()); - StringRef OpStr = isLeftComp ? BinOp::getOpcodeStr(LHSopc) - : BinOp::getOpcodeStr(RHSopc); + StringRef OpStr = isLeftComp ? LHSBO->getOpcodeStr() : RHSBO->getOpcodeStr(); SourceRange ParensRange = isLeftComp ? - SourceRange(cast<BinOp>(LHSExpr)->getRHS()->getLocStart(), - RHSExpr->getLocEnd()) - : SourceRange(LHSExpr->getLocStart(), - cast<BinOp>(RHSExpr)->getLHS()->getLocStart()); + SourceRange(LHSBO->getRHS()->getLocStart(), RHSExpr->getLocEnd()) + : SourceRange(LHSExpr->getLocStart(), RHSBO->getLHS()->getLocStart()); Self.Diag(OpLoc, diag::warn_precedence_bitwise_rel) - << DiagRange << BinOp::getOpcodeStr(Opc) << OpStr; + << DiagRange << BinaryOperator::getOpcodeStr(Opc) << OpStr; SuggestParentheses(Self, OpLoc, Self.PDiag(diag::note_precedence_silence) << OpStr, (isLeftComp ? LHSExpr : RHSExpr)->getSourceRange()); SuggestParentheses(Self, OpLoc, - Self.PDiag(diag::note_precedence_bitwise_first) << BinOp::getOpcodeStr(Opc), + Self.PDiag(diag::note_precedence_bitwise_first) + << BinaryOperator::getOpcodeStr(Opc), ParensRange); } @@ -8806,7 +9011,8 @@ ExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc, case UO_Not: // bitwise complement Input = UsualUnaryConversions(Input.take()); - if (Input.isInvalid()) return ExprError(); + if (Input.isInvalid()) + return ExprError(); resultType = Input.get()->getType(); if (resultType->isDependentType()) break; @@ -8814,12 +9020,22 @@ ExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc, if (resultType->isComplexType() || resultType->isComplexIntegerType()) // C99 does not support '~' for complex conjugation. Diag(OpLoc, diag::ext_integer_complement_complex) - << resultType << Input.get()->getSourceRange(); + << resultType << Input.get()->getSourceRange(); else if (resultType->hasIntegerRepresentation()) break; - else { + else if (resultType->isExtVectorType()) { + if (Context.getLangOpts().OpenCL) { + // OpenCL v1.1 s6.3.f: The bitwise operator not (~) does not operate + // on vector float types. + QualType T = resultType->getAs<ExtVectorType>()->getElementType(); + if (!T->isIntegerType()) + return ExprError(Diag(OpLoc, diag::err_typecheck_unary_expr) + << resultType << Input.get()->getSourceRange()); + } + break; + } else { return ExprError(Diag(OpLoc, diag::err_typecheck_unary_expr) - << resultType << Input.get()->getSourceRange()); + << resultType << Input.get()->getSourceRange()); } break; @@ -8830,7 +9046,7 @@ ExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc, resultType = Input.get()->getType(); // Though we still have to promote half FP to float... - if (resultType->isHalfType()) { + if (resultType->isHalfType() && !Context.getLangOpts().NativeHalfType) { Input = ImpCastExprToType(Input.take(), Context.FloatTy, CK_FloatingCast).take(); resultType = Context.FloatTy; } @@ -8844,8 +9060,24 @@ ExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc, // operand contextually converted to bool. Input = ImpCastExprToType(Input.take(), Context.BoolTy, ScalarTypeToBooleanCastKind(resultType)); + } else if (Context.getLangOpts().OpenCL && + Context.getLangOpts().OpenCLVersion < 120) { + // OpenCL v1.1 6.3.h: The logical operator not (!) does not + // operate on scalar float types. + if (!resultType->isIntegerType()) + return ExprError(Diag(OpLoc, diag::err_typecheck_unary_expr) + << resultType << Input.get()->getSourceRange()); } } else if (resultType->isExtVectorType()) { + if (Context.getLangOpts().OpenCL && + Context.getLangOpts().OpenCLVersion < 120) { + // OpenCL v1.1 6.3.h: The logical operator not (!) does not + // operate on vector float types. + QualType T = resultType->getAs<ExtVectorType>()->getElementType(); + if (!T->isIntegerType()) + return ExprError(Diag(OpLoc, diag::err_typecheck_unary_expr) + << resultType << Input.get()->getSourceRange()); + } // Vector logical not returns the signed variant of the operand type. resultType = GetSignedVectorType(resultType); break; @@ -9210,9 +9442,9 @@ ExprResult Sema::BuildBuiltinOffsetOf(SourceLocation BuiltinLoc, // If type is not a standard-layout class (Clause 9), the results are // undefined. if (CXXRecordDecl *CRD = dyn_cast<CXXRecordDecl>(RD)) { - bool IsSafe = LangOpts.CPlusPlus0x? CRD->isStandardLayout() : CRD->isPOD(); + bool IsSafe = LangOpts.CPlusPlus11? CRD->isStandardLayout() : CRD->isPOD(); unsigned DiagID = - LangOpts.CPlusPlus0x? diag::warn_offsetof_non_standardlayout_type + LangOpts.CPlusPlus11? diag::warn_offsetof_non_standardlayout_type : diag::warn_offsetof_non_pod_type; if (!IsSafe && !DidWarnAboutNonPOD && @@ -9379,8 +9611,7 @@ void Sema::ActOnBlockArguments(SourceLocation CaretLoc, Declarator &ParamInfo, FunctionProtoType::ExtProtoInfo EPI; EPI.HasTrailingReturn = false; EPI.TypeQuals |= DeclSpec::TQ_const; - T = Context.getFunctionType(Context.DependentTy, /*Args=*/0, /*NumArgs=*/0, - EPI); + T = Context.getFunctionType(Context.DependentTy, ArrayRef<QualType>(), EPI); Sig = Context.getTrivialTypeSourceInfo(T); } @@ -9394,8 +9625,7 @@ void Sema::ActOnBlockArguments(SourceLocation CaretLoc, Declarator &ParamInfo, FunctionProtoTypeLoc ExplicitSignature; TypeLoc tmp = Sig->getTypeLoc().IgnoreParens(); - if (isa<FunctionProtoTypeLoc>(tmp)) { - ExplicitSignature = cast<FunctionProtoTypeLoc>(tmp); + if ((ExplicitSignature = tmp.getAs<FunctionProtoTypeLoc>())) { // Check whether that explicit signature was synthesized by // GetTypeForDeclarator. If so, don't save that as part of the @@ -9560,7 +9790,7 @@ ExprResult Sema::ActOnBlockStmtExpr(SourceLocation CaretLoc, if (isa<FunctionNoProtoType>(FTy)) { FunctionProtoType::ExtProtoInfo EPI; EPI.ExtInfo = Ext; - BlockTy = Context.getFunctionType(RetTy, 0, 0, EPI); + BlockTy = Context.getFunctionType(RetTy, ArrayRef<QualType>(), EPI); // Otherwise, if we don't need to change anything about the function type, // preserve its sugar structure. @@ -9574,17 +9804,18 @@ ExprResult Sema::ActOnBlockStmtExpr(SourceLocation CaretLoc, FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo(); EPI.TypeQuals = 0; // FIXME: silently? EPI.ExtInfo = Ext; - BlockTy = Context.getFunctionType(RetTy, - FPT->arg_type_begin(), - FPT->getNumArgs(), - EPI); + BlockTy = + Context.getFunctionType(RetTy, + ArrayRef<QualType>(FPT->arg_type_begin(), + FPT->getNumArgs()), + EPI); } // If we don't have a function type, just build one from nothing. } else { FunctionProtoType::ExtProtoInfo EPI; EPI.ExtInfo = FunctionType::ExtInfo().withNoReturn(NoReturn); - BlockTy = Context.getFunctionType(RetTy, 0, 0, EPI); + BlockTy = Context.getFunctionType(RetTy, ArrayRef<QualType>(), EPI); } DiagnoseUnusedParameters(BSI->TheDecl->param_begin(), @@ -9715,11 +9946,11 @@ ExprResult Sema::BuildVAArgExpr(SourceLocation BuiltinLoc, if (TInfo->getType()->isSpecificBuiltinType(BuiltinType::Float)) PromoteType = Context.DoubleTy; if (!PromoteType.isNull()) - Diag(TInfo->getTypeLoc().getBeginLoc(), - diag::warn_second_parameter_to_va_arg_never_compatible) - << TInfo->getType() - << PromoteType - << TInfo->getTypeLoc().getSourceRange(); + DiagRuntimeBehavior(TInfo->getTypeLoc().getBeginLoc(), E, + PDiag(diag::warn_second_parameter_to_va_arg_never_compatible) + << TInfo->getType() + << PromoteType + << TInfo->getTypeLoc().getSourceRange()); } QualType T = TInfo->getType().getNonLValueExprType(Context); @@ -9932,6 +10163,9 @@ bool Sema::DiagnoseAssignmentResult(AssignConvertType ConvTy, if (CheckInferredResultType) EmitRelatedResultTypeNote(SrcExpr); + + if (Action == AA_Returning && ConvTy == IncompatiblePointer) + EmitRelatedResultTypeNoteForReturn(DstType); if (Complained) *Complained = true; @@ -9980,7 +10214,7 @@ Sema::VerifyIntegerConstantExpression(Expr *E, llvm::APSInt *Result, bool AllowFold) { SourceLocation DiagLoc = E->getLocStart(); - if (getLangOpts().CPlusPlus0x) { + if (getLangOpts().CPlusPlus11) { // C++11 [expr.const]p5: // If an expression of literal class type is used in a context where an // integral constant expression is required, then that class type shall @@ -10107,14 +10341,14 @@ Sema::VerifyIntegerConstantExpression(Expr *E, llvm::APSInt *Result, // Circumvent ICE checking in C++11 to avoid evaluating the expression twice // in the non-ICE case. - if (!getLangOpts().CPlusPlus0x && E->isIntegerConstantExpr(Context)) { + if (!getLangOpts().CPlusPlus11 && E->isIntegerConstantExpr(Context)) { if (Result) *Result = E->EvaluateKnownConstInt(Context); return Owned(E); } Expr::EvalResult EvalResult; - llvm::SmallVector<PartialDiagnosticAt, 8> Notes; + SmallVector<PartialDiagnosticAt, 8> Notes; EvalResult.Diag = &Notes; // Try to evaluate the expression, and produce diagnostics explaining why it's @@ -10125,7 +10359,7 @@ Sema::VerifyIntegerConstantExpression(Expr *E, llvm::APSInt *Result, // In C++11, we can rely on diagnostics being produced for any expression // which is not a constant expression. If no diagnostics were produced, then // this is a constant expression. - if (Folded && getLangOpts().CPlusPlus0x && Notes.empty()) { + if (Folded && getLangOpts().CPlusPlus11 && Notes.empty()) { if (Result) *Result = EvalResult.Val.getInt(); return Owned(E); @@ -10211,7 +10445,7 @@ namespace { }; } -ExprResult Sema::TranformToPotentiallyEvaluated(Expr *E) { +ExprResult Sema::TransformToPotentiallyEvaluated(Expr *E) { assert(ExprEvalContexts.back().Context == Unevaluated && "Should only transform unevaluated expressions"); ExprEvalContexts.back().Context = @@ -10302,7 +10536,7 @@ void Sema::DiscardCleanupsInEvaluationContext() { ExprResult Sema::HandleExprEvaluationContextForTypeof(Expr *E) { if (!E->getType()->isVariablyModifiedType()) return E; - return TranformToPotentiallyEvaluated(E); + return TransformToPotentiallyEvaluated(E); } static bool IsPotentiallyEvaluatedContext(Sema &SemaRef) { @@ -10395,6 +10629,9 @@ void Sema::MarkFunctionReferenced(SourceLocation Loc, FunctionDecl *Func) { if (!Constructor->isUsed(false)) DefineImplicitMoveConstructor(Loc, Constructor); } + } else if (Constructor->getInheritedConstructor()) { + if (!Constructor->isUsed(false)) + DefineInheritingConstructor(Loc, Constructor); } MarkVTableUsed(Loc, Constructor->getParent()); @@ -10488,13 +10725,26 @@ void Sema::MarkFunctionReferenced(SourceLocation Loc, FunctionDecl *Func) { } // Keep track of used but undefined functions. - if (!Func->isPure() && !Func->hasBody() && - Func->getLinkage() != ExternalLinkage) { - SourceLocation &old = UndefinedInternals[Func->getCanonicalDecl()]; - if (old.isInvalid()) old = Loc; + if (!Func->isDefined()) { + if (mightHaveNonExternalLinkage(Func)) + UndefinedButUsed.insert(std::make_pair(Func->getCanonicalDecl(), Loc)); + else if (Func->getMostRecentDecl()->isInlined() && + (LangOpts.CPlusPlus || !LangOpts.GNUInline) && + !Func->getMostRecentDecl()->hasAttr<GNUInlineAttr>()) + UndefinedButUsed.insert(std::make_pair(Func->getCanonicalDecl(), Loc)); + } + + // Normally the must current decl is marked used while processing the use and + // any subsequent decls are marked used by decl merging. This fails with + // template instantiation since marking can happen at the end of the file + // and, because of the two phase lookup, this function is called with at + // decl in the middle of a decl chain. We loop to maintain the invariant + // that once a decl is used, all decls after it are also used. + for (FunctionDecl *F = Func->getMostRecentDecl();; F = F->getPreviousDecl()) { + F->setUsed(true); + if (F == Func) + break; } - - Func->setUsed(true); } static void @@ -10572,7 +10822,7 @@ static ExprResult captureInLambda(Sema &S, LambdaScopeInfo *LSI, // Introduce a new evaluation context for the initialization, so // that temporaries introduced as part of the capture are retained // to be re-"exported" from the lambda expression itself. - S.PushExpressionEvaluationContext(Sema::PotentiallyEvaluated); + EnterExpressionEvaluationContext scope(S, Sema::PotentiallyEvaluated); // C++ [expr.prim.labda]p12: // An entity captured by a lambda-expression is odr-used (3.2) in @@ -10604,7 +10854,7 @@ static ExprResult captureInLambda(Sema &S, LambdaScopeInfo *LSI, = VarDecl::Create(S.Context, S.CurContext, Loc, Loc, IterationVarName, SizeType, S.Context.getTrivialTypeSourceInfo(SizeType, Loc), - SC_None, SC_None); + SC_None); IndexVariables.push_back(IterationVar); LSI->ArrayIndexVars.push_back(IterationVar); @@ -10623,7 +10873,6 @@ static ExprResult captureInLambda(Sema &S, LambdaScopeInfo *LSI, if (Subscript.isInvalid()) { S.CleanupVarDeclMarking(); S.DiscardCleanupsInEvaluationContext(); - S.PopExpressionEvaluationContext(); return ExprError(); } @@ -10659,7 +10908,6 @@ static ExprResult captureInLambda(Sema &S, LambdaScopeInfo *LSI, // Exit the expression evaluation context used for the capture. S.CleanupVarDeclMarking(); S.DiscardCleanupsInEvaluationContext(); - S.PopExpressionEvaluationContext(); return Result; } @@ -10748,7 +10996,22 @@ bool Sema::tryCaptureVariable(VarDecl *Var, SourceLocation Loc, } return true; } - + // Prohibit structs with flexible array members too. + // We cannot capture what is in the tail end of the struct. + if (const RecordType *VTTy = Var->getType()->getAs<RecordType>()) { + if (VTTy->getDecl()->hasFlexibleArrayMember()) { + if (BuildAndDiagnose) { + if (IsBlock) + Diag(Loc, diag::err_ref_flexarray_type); + else + Diag(Loc, diag::err_lambda_capture_flexarray_type) + << Var->getDeclName(); + Diag(Var->getLocation(), diag::note_previous_decl) + << Var->getDeclName(); + } + return true; + } + } // Lambdas are not allowed to capture __block variables; they don't // support the expected semantics. if (IsLambda && HasBlocksAttr) { @@ -10830,13 +11093,18 @@ bool Sema::tryCaptureVariable(VarDecl *Var, SourceLocation Loc, // actually requires the destructor. if (isa<ParmVarDecl>(Var)) FinalizeVarWithDestructor(Var, Record); - + + // Enter a new evaluation context to insulate the copy + // full-expression. + EnterExpressionEvaluationContext scope(*this, PotentiallyEvaluated); + // According to the blocks spec, the capture of a variable from // the stack requires a const copy constructor. This is not true // of the copy/move done to move a __block variable to the heap. - Expr *DeclRef = new (Context) DeclRefExpr(Var, false, + Expr *DeclRef = new (Context) DeclRefExpr(Var, Nested, DeclRefType.withConst(), VK_LValue, Loc); + ExprResult Result = PerformCopyInitialization( InitializedEntity::InitializeBlock(Var->getLocation(), @@ -10921,7 +11189,7 @@ bool Sema::tryCaptureVariable(VarDecl *Var, SourceLocation Loc, if (BuildAndDiagnose) { ExprResult Result = captureInLambda(*this, LSI, Var, CaptureType, DeclRefType, Loc, - I == N-1); + Nested); if (!Result.isInvalid()) CopyExpr = Result.take(); } @@ -10978,7 +11246,7 @@ static void MarkVarDeclODRUsed(Sema &SemaRef, VarDecl *Var, if (Var->hasDefinition(SemaRef.Context) == VarDecl::DeclarationOnly && Var->getLinkage() != ExternalLinkage && !(Var->isStaticDataMember() && Var->hasInit())) { - SourceLocation &old = SemaRef.UndefinedInternals[Var->getCanonicalDecl()]; + SourceLocation &old = SemaRef.UndefinedButUsed[Var->getCanonicalDecl()]; if (old.isInvalid()) old = Loc; } @@ -11090,13 +11358,13 @@ void Sema::MarkVariableReferenced(SourceLocation Loc, VarDecl *Var) { } static void MarkExprReferenced(Sema &SemaRef, SourceLocation Loc, - Decl *D, Expr *E) { + Decl *D, Expr *E, bool OdrUse) { if (VarDecl *Var = dyn_cast<VarDecl>(D)) { DoMarkVarDeclReferenced(SemaRef, Loc, Var, E); return; } - SemaRef.MarkAnyDeclReferenced(Loc, D); + SemaRef.MarkAnyDeclReferenced(Loc, D, OdrUse); // If this is a call to a method via a cast, also mark the method in the // derived class used in case codegen can devirtualize the call. @@ -11111,32 +11379,58 @@ static void MarkExprReferenced(Sema &SemaRef, SourceLocation Loc, if (!MostDerivedClassDecl) return; CXXMethodDecl *DM = MD->getCorrespondingMethodInClass(MostDerivedClassDecl); - if (!DM) + if (!DM || DM->isPure()) return; - SemaRef.MarkAnyDeclReferenced(Loc, DM); + SemaRef.MarkAnyDeclReferenced(Loc, DM, OdrUse); } /// \brief Perform reference-marking and odr-use handling for a DeclRefExpr. void Sema::MarkDeclRefReferenced(DeclRefExpr *E) { - MarkExprReferenced(*this, E->getLocation(), E->getDecl(), E); + // TODO: update this with DR# once a defect report is filed. + // C++11 defect. The address of a pure member should not be an ODR use, even + // if it's a qualified reference. + bool OdrUse = true; + if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(E->getDecl())) + if (Method->isVirtual()) + OdrUse = false; + MarkExprReferenced(*this, E->getLocation(), E->getDecl(), E, OdrUse); } /// \brief Perform reference-marking and odr-use handling for a MemberExpr. void Sema::MarkMemberReferenced(MemberExpr *E) { - MarkExprReferenced(*this, E->getMemberLoc(), E->getMemberDecl(), E); + // C++11 [basic.def.odr]p2: + // A non-overloaded function whose name appears as a potentially-evaluated + // expression or a member of a set of candidate functions, if selected by + // overload resolution when referred to from a potentially-evaluated + // expression, is odr-used, unless it is a pure virtual function and its + // name is not explicitly qualified. + bool OdrUse = true; + if (!E->hasQualifier()) { + if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(E->getMemberDecl())) + if (Method->isPure()) + OdrUse = false; + } + SourceLocation Loc = E->getMemberLoc().isValid() ? + E->getMemberLoc() : E->getLocStart(); + MarkExprReferenced(*this, Loc, E->getMemberDecl(), E, OdrUse); } /// \brief Perform marking for a reference to an arbitrary declaration. It /// marks the declaration referenced, and performs odr-use checking for functions /// and variables. This method should not be used when building an normal /// expression which refers to a variable. -void Sema::MarkAnyDeclReferenced(SourceLocation Loc, Decl *D) { - if (VarDecl *VD = dyn_cast<VarDecl>(D)) - MarkVariableReferenced(Loc, VD); - else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) - MarkFunctionReferenced(Loc, FD); - else - D->setReferenced(); +void Sema::MarkAnyDeclReferenced(SourceLocation Loc, Decl *D, bool OdrUse) { + if (OdrUse) { + if (VarDecl *VD = dyn_cast<VarDecl>(D)) { + MarkVariableReferenced(Loc, VD); + return; + } + if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { + MarkFunctionReferenced(Loc, FD); + return; + } + } + D->setReferenced(); } namespace { @@ -11161,7 +11455,7 @@ bool MarkReferencedDecls::TraverseTemplateArgument( const TemplateArgument &Arg) { if (Arg.getKind() == TemplateArgument::Declaration) { if (Decl *D = Arg.getAsDecl()) - S.MarkAnyDeclReferenced(Loc, D); + S.MarkAnyDeclReferenced(Loc, D, true); } return Inherited::TraverseTemplateArgument(Arg); @@ -11685,10 +11979,11 @@ ExprResult RebuildUnknownAnyExpr::VisitCallExpr(CallExpr *E) { // Rebuild the function type, replacing the result type with DestType. if (const FunctionProtoType *Proto = dyn_cast<FunctionProtoType>(FnType)) - DestType = S.Context.getFunctionType(DestType, - Proto->arg_type_begin(), - Proto->getNumArgs(), - Proto->getExtProtoInfo()); + DestType = + S.Context.getFunctionType(DestType, + ArrayRef<QualType>(Proto->arg_type_begin(), + Proto->getNumArgs()), + Proto->getExtProtoInfo()); else DestType = S.Context.getFunctionNoProtoType(DestType, FnType->getExtInfo()); @@ -11850,6 +12145,29 @@ ExprResult Sema::forceUnknownAnyToType(Expr *E, QualType ToType) { return RebuildUnknownAnyExpr(*this, ToType).Visit(E); } +ExprResult Sema::checkUnknownAnyArg(SourceLocation callLoc, + Expr *arg, QualType ¶mType) { + // If the syntactic form of the argument is not an explicit cast of + // any sort, just do default argument promotion. + ExplicitCastExpr *castArg = dyn_cast<ExplicitCastExpr>(arg->IgnoreParens()); + if (!castArg) { + ExprResult result = DefaultArgumentPromotion(arg); + if (result.isInvalid()) return ExprError(); + paramType = result.get()->getType(); + return result; + } + + // Otherwise, use the type that was written in the explicit cast. + assert(!arg->hasPlaceholderType()); + paramType = castArg->getTypeAsWritten(); + + // Copy-initialize a parameter of that type. + InitializedEntity entity = + InitializedEntity::InitializeParameter(Context, paramType, + /*consumed*/ false); + return PerformCopyInitialization(entity, callLoc, Owned(arg)); +} + static ExprResult diagnoseUnknownAnyExpr(Sema &S, Expr *E) { Expr *orig = E; unsigned diagID = diag::err_uncasted_use_of_unknown_any; |