diff options
Diffstat (limited to 'lib/Sema/SemaChecking.cpp')
-rw-r--r-- | lib/Sema/SemaChecking.cpp | 844 |
1 files changed, 664 insertions, 180 deletions
diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp index a0998a4..0b95c48 100644 --- a/lib/Sema/SemaChecking.cpp +++ b/lib/Sema/SemaChecking.cpp @@ -32,9 +32,9 @@ #include "clang/Sema/Lookup.h" #include "clang/Sema/ScopeInfo.h" #include "clang/Sema/Sema.h" -#include "llvm/ADT/BitVector.h" -#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/SmallBitVector.h" #include "llvm/ADT/SmallString.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/Support/ConvertUTF.h" #include "llvm/Support/raw_ostream.h" #include <limits> @@ -95,6 +95,22 @@ static bool SemaBuiltinAnnotation(Sema &S, CallExpr *TheCall) { return false; } +/// Check that the argument to __builtin_addressof is a glvalue, and set the +/// result type to the corresponding pointer type. +static bool SemaBuiltinAddressof(Sema &S, CallExpr *TheCall) { + if (checkArgCount(S, TheCall, 1)) + return true; + + ExprResult Arg(S.Owned(TheCall->getArg(0))); + QualType ResultType = S.CheckAddressOfOperand(Arg, TheCall->getLocStart()); + if (ResultType.isNull()) + return true; + + TheCall->setArg(0, Arg.take()); + TheCall->setType(ResultType); + return false; +} + ExprResult Sema::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { ExprResult TheCallResult(Owned(TheCall)); @@ -275,6 +291,10 @@ Sema::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { if (SemaBuiltinAnnotation(*this, TheCall)) return ExprError(); break; + case Builtin::BI__builtin_addressof: + if (SemaBuiltinAddressof(*this, TheCall)) + return ExprError(); + break; } // Since the target specific builtins for each arch overlap, only check those @@ -286,6 +306,10 @@ Sema::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { if (CheckARMBuiltinFunctionCall(BuiltinID, TheCall)) return ExprError(); break; + case llvm::Triple::aarch64: + if (CheckAArch64BuiltinFunctionCall(BuiltinID, TheCall)) + return ExprError(); + break; case llvm::Triple::mips: case llvm::Triple::mipsel: case llvm::Triple::mips64: @@ -315,6 +339,7 @@ static unsigned RFT(unsigned t, bool shift = false) { case NeonTypeFlags::Int32: return shift ? 31 : (2 << IsQuad) - 1; case NeonTypeFlags::Int64: + case NeonTypeFlags::Poly64: return shift ? 63 : (1 << IsQuad) - 1; case NeonTypeFlags::Float16: assert(!shift && "cannot shift float types!"); @@ -322,6 +347,9 @@ static unsigned RFT(unsigned t, bool shift = false) { case NeonTypeFlags::Float32: assert(!shift && "cannot shift float types!"); return (2 << IsQuad) - 1; + case NeonTypeFlags::Float64: + assert(!shift && "cannot shift float types!"); + return (1 << IsQuad) - 1; } llvm_unreachable("Invalid NeonTypeFlag!"); } @@ -329,7 +357,8 @@ static unsigned RFT(unsigned t, bool shift = false) { /// getNeonEltType - Return the QualType corresponding to the elements of /// the vector type specified by the NeonTypeFlags. This is used to check /// the pointer arguments for Neon load/store intrinsics. -static QualType getNeonEltType(NeonTypeFlags Flags, ASTContext &Context) { +static QualType getNeonEltType(NeonTypeFlags Flags, ASTContext &Context, + bool IsAArch64) { switch (Flags.getEltType()) { case NeonTypeFlags::Int8: return Flags.isUnsigned() ? Context.UnsignedCharTy : Context.SignedCharTy; @@ -340,20 +369,213 @@ static QualType getNeonEltType(NeonTypeFlags Flags, ASTContext &Context) { case NeonTypeFlags::Int64: return Flags.isUnsigned() ? Context.UnsignedLongLongTy : Context.LongLongTy; case NeonTypeFlags::Poly8: - return Context.SignedCharTy; + return IsAArch64 ? Context.UnsignedCharTy : Context.SignedCharTy; case NeonTypeFlags::Poly16: - return Context.ShortTy; + return IsAArch64 ? Context.UnsignedShortTy : Context.ShortTy; + case NeonTypeFlags::Poly64: + return Context.UnsignedLongLongTy; case NeonTypeFlags::Float16: - return Context.UnsignedShortTy; + return Context.HalfTy; case NeonTypeFlags::Float32: return Context.FloatTy; + case NeonTypeFlags::Float64: + return Context.DoubleTy; } llvm_unreachable("Invalid NeonTypeFlag!"); } +bool Sema::CheckAArch64BuiltinFunctionCall(unsigned BuiltinID, + CallExpr *TheCall) { + + llvm::APSInt Result; + + uint64_t mask = 0; + unsigned TV = 0; + int PtrArgNum = -1; + bool HasConstPtr = false; + switch (BuiltinID) { +#define GET_NEON_AARCH64_OVERLOAD_CHECK +#include "clang/Basic/arm_neon.inc" +#undef GET_NEON_AARCH64_OVERLOAD_CHECK + } + + // For NEON intrinsics which are overloaded on vector element type, validate + // the immediate which specifies which variant to emit. + unsigned ImmArg = TheCall->getNumArgs() - 1; + if (mask) { + if (SemaBuiltinConstantArg(TheCall, ImmArg, Result)) + return true; + + TV = Result.getLimitedValue(64); + if ((TV > 63) || (mask & (1ULL << TV)) == 0) + return Diag(TheCall->getLocStart(), diag::err_invalid_neon_type_code) + << TheCall->getArg(ImmArg)->getSourceRange(); + } + + if (PtrArgNum >= 0) { + // Check that pointer arguments have the specified type. + Expr *Arg = TheCall->getArg(PtrArgNum); + if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Arg)) + Arg = ICE->getSubExpr(); + ExprResult RHS = DefaultFunctionArrayLvalueConversion(Arg); + QualType RHSTy = RHS.get()->getType(); + QualType EltTy = getNeonEltType(NeonTypeFlags(TV), Context, true); + if (HasConstPtr) + EltTy = EltTy.withConst(); + QualType LHSTy = Context.getPointerType(EltTy); + AssignConvertType ConvTy; + ConvTy = CheckSingleAssignmentConstraints(LHSTy, RHS); + if (RHS.isInvalid()) + return true; + if (DiagnoseAssignmentResult(ConvTy, Arg->getLocStart(), LHSTy, RHSTy, + RHS.get(), AA_Assigning)) + return true; + } + + // For NEON intrinsics which take an immediate value as part of the + // instruction, range check them here. + unsigned i = 0, l = 0, u = 0; + switch (BuiltinID) { + default: + return false; +#define GET_NEON_AARCH64_IMMEDIATE_CHECK +#include "clang/Basic/arm_neon.inc" +#undef GET_NEON_AARCH64_IMMEDIATE_CHECK + } + ; + + // We can't check the value of a dependent argument. + if (TheCall->getArg(i)->isTypeDependent() || + TheCall->getArg(i)->isValueDependent()) + return false; + + // Check that the immediate argument is actually a constant. + if (SemaBuiltinConstantArg(TheCall, i, Result)) + return true; + + // Range check against the upper/lower values for this isntruction. + unsigned Val = Result.getZExtValue(); + if (Val < l || Val > (u + l)) + return Diag(TheCall->getLocStart(), diag::err_argument_invalid_range) + << l << u + l << TheCall->getArg(i)->getSourceRange(); + + return false; +} + +bool Sema::CheckARMBuiltinExclusiveCall(unsigned BuiltinID, CallExpr *TheCall) { + assert((BuiltinID == ARM::BI__builtin_arm_ldrex || + BuiltinID == ARM::BI__builtin_arm_strex) && + "unexpected ARM builtin"); + bool IsLdrex = BuiltinID == ARM::BI__builtin_arm_ldrex; + + DeclRefExpr *DRE =cast<DeclRefExpr>(TheCall->getCallee()->IgnoreParenCasts()); + + // Ensure that we have the proper number of arguments. + if (checkArgCount(*this, TheCall, IsLdrex ? 1 : 2)) + return true; + + // Inspect the pointer argument of the atomic builtin. This should always be + // a pointer type, whose element is an integral scalar or pointer type. + // Because it is a pointer type, we don't have to worry about any implicit + // casts here. + Expr *PointerArg = TheCall->getArg(IsLdrex ? 0 : 1); + ExprResult PointerArgRes = DefaultFunctionArrayLvalueConversion(PointerArg); + if (PointerArgRes.isInvalid()) + return true; + PointerArg = PointerArgRes.take(); + + const PointerType *pointerType = PointerArg->getType()->getAs<PointerType>(); + if (!pointerType) { + Diag(DRE->getLocStart(), diag::err_atomic_builtin_must_be_pointer) + << PointerArg->getType() << PointerArg->getSourceRange(); + return true; + } + + // ldrex takes a "const volatile T*" and strex takes a "volatile T*". Our next + // task is to insert the appropriate casts into the AST. First work out just + // what the appropriate type is. + QualType ValType = pointerType->getPointeeType(); + QualType AddrType = ValType.getUnqualifiedType().withVolatile(); + if (IsLdrex) + AddrType.addConst(); + + // Issue a warning if the cast is dodgy. + CastKind CastNeeded = CK_NoOp; + if (!AddrType.isAtLeastAsQualifiedAs(ValType)) { + CastNeeded = CK_BitCast; + Diag(DRE->getLocStart(), diag::ext_typecheck_convert_discards_qualifiers) + << PointerArg->getType() + << Context.getPointerType(AddrType) + << AA_Passing << PointerArg->getSourceRange(); + } + + // Finally, do the cast and replace the argument with the corrected version. + AddrType = Context.getPointerType(AddrType); + PointerArgRes = ImpCastExprToType(PointerArg, AddrType, CastNeeded); + if (PointerArgRes.isInvalid()) + return true; + PointerArg = PointerArgRes.take(); + + TheCall->setArg(IsLdrex ? 0 : 1, PointerArg); + + // In general, we allow ints, floats and pointers to be loaded and stored. + if (!ValType->isIntegerType() && !ValType->isAnyPointerType() && + !ValType->isBlockPointerType() && !ValType->isFloatingType()) { + Diag(DRE->getLocStart(), diag::err_atomic_builtin_must_be_pointer_intfltptr) + << PointerArg->getType() << PointerArg->getSourceRange(); + return true; + } + + // But ARM doesn't have instructions to deal with 128-bit versions. + if (Context.getTypeSize(ValType) > 64) { + Diag(DRE->getLocStart(), diag::err_atomic_exclusive_builtin_pointer_size) + << PointerArg->getType() << PointerArg->getSourceRange(); + return true; + } + + switch (ValType.getObjCLifetime()) { + case Qualifiers::OCL_None: + case Qualifiers::OCL_ExplicitNone: + // okay + break; + + case Qualifiers::OCL_Weak: + case Qualifiers::OCL_Strong: + case Qualifiers::OCL_Autoreleasing: + Diag(DRE->getLocStart(), diag::err_arc_atomic_ownership) + << ValType << PointerArg->getSourceRange(); + return true; + } + + + if (IsLdrex) { + TheCall->setType(ValType); + return false; + } + + // Initialize the argument to be stored. + ExprResult ValArg = TheCall->getArg(0); + InitializedEntity Entity = InitializedEntity::InitializeParameter( + Context, ValType, /*consume*/ false); + ValArg = PerformCopyInitialization(Entity, SourceLocation(), ValArg); + if (ValArg.isInvalid()) + return true; + TheCall->setArg(0, ValArg.get()); + + // __builtin_arm_strex always returns an int. It's marked as such in the .def, + // but the custom checker bypasses all default analysis. + TheCall->setType(Context.IntTy); + return false; +} + bool Sema::CheckARMBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { llvm::APSInt Result; + if (BuiltinID == ARM::BI__builtin_arm_ldrex || + BuiltinID == ARM::BI__builtin_arm_strex) { + return CheckARMBuiltinExclusiveCall(BuiltinID, TheCall); + } + uint64_t mask = 0; unsigned TV = 0; int PtrArgNum = -1; @@ -384,7 +606,7 @@ bool Sema::CheckARMBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { Arg = ICE->getSubExpr(); ExprResult RHS = DefaultFunctionArrayLvalueConversion(Arg); QualType RHSTy = RHS.get()->getType(); - QualType EltTy = getNeonEltType(NeonTypeFlags(TV), Context); + QualType EltTy = getNeonEltType(NeonTypeFlags(TV), Context, false); if (HasConstPtr) EltTy = EltTy.withConst(); QualType LHSTy = Context.getPointerType(EltTy); @@ -406,6 +628,8 @@ bool Sema::CheckARMBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { case ARM::BI__builtin_arm_usat: i = 1; u = 31; break; case ARM::BI__builtin_arm_vcvtr_f: case ARM::BI__builtin_arm_vcvtr_d: i = 1; u = 1; break; + case ARM::BI__builtin_arm_dmb: + case ARM::BI__builtin_arm_dsb: l = 0; u = 15; break; #define GET_NEON_IMMEDIATE_CHECK #include "clang/Basic/arm_neon.inc" #undef GET_NEON_IMMEDIATE_CHECK @@ -494,36 +718,50 @@ void Sema::checkCall(NamedDecl *FDecl, SourceLocation Loc, SourceRange Range, VariadicCallType CallType) { + // FIXME: We should check as much as we can in the template definition. if (CurContext->isDependentContext()) return; // Printf and scanf checking. - bool HandledFormatString = false; - for (specific_attr_iterator<FormatAttr> - I = FDecl->specific_attr_begin<FormatAttr>(), - E = FDecl->specific_attr_end<FormatAttr>(); I != E ; ++I) - if (CheckFormatArguments(*I, Args, IsMemberFunction, CallType, Loc, Range)) - HandledFormatString = true; + llvm::SmallBitVector CheckedVarArgs; + if (FDecl) { + for (specific_attr_iterator<FormatAttr> + I = FDecl->specific_attr_begin<FormatAttr>(), + E = FDecl->specific_attr_end<FormatAttr>(); + I != E; ++I) { + // Only create vector if there are format attributes. + CheckedVarArgs.resize(Args.size()); + + CheckFormatArguments(*I, Args, IsMemberFunction, CallType, Loc, Range, + CheckedVarArgs); + } + } // Refuse POD arguments that weren't caught by the format string // checks above. - if (!HandledFormatString && CallType != VariadicDoesNotApply) + if (CallType != VariadicDoesNotApply) { for (unsigned ArgIdx = NumProtoArgs; ArgIdx < Args.size(); ++ArgIdx) { // Args[ArgIdx] can be null in malformed code. - if (const Expr *Arg = Args[ArgIdx]) - variadicArgumentPODCheck(Arg, CallType); + if (const Expr *Arg = Args[ArgIdx]) { + if (CheckedVarArgs.empty() || !CheckedVarArgs[ArgIdx]) + checkVariadicArgument(Arg, CallType); + } } + } - for (specific_attr_iterator<NonNullAttr> - I = FDecl->specific_attr_begin<NonNullAttr>(), - E = FDecl->specific_attr_end<NonNullAttr>(); I != E; ++I) - CheckNonNullArguments(*I, Args.data(), Loc); + if (FDecl) { + for (specific_attr_iterator<NonNullAttr> + I = FDecl->specific_attr_begin<NonNullAttr>(), + E = FDecl->specific_attr_end<NonNullAttr>(); I != E; ++I) + CheckNonNullArguments(*I, Args.data(), Loc); - // Type safety checking. - for (specific_attr_iterator<ArgumentWithTypeTagAttr> - i = FDecl->specific_attr_begin<ArgumentWithTypeTagAttr>(), - e = FDecl->specific_attr_end<ArgumentWithTypeTagAttr>(); i != e; ++i) { - CheckArgumentWithTypeTag(*i, Args.data()); + // Type safety checking. + for (specific_attr_iterator<ArgumentWithTypeTagAttr> + i = FDecl->specific_attr_begin<ArgumentWithTypeTagAttr>(), + e = FDecl->specific_attr_end<ArgumentWithTypeTagAttr>(); + i != e; ++i) { + CheckArgumentWithTypeTag(*i, Args.data()); + } } } @@ -597,18 +835,24 @@ bool Sema::CheckObjCMethodCall(ObjCMethodDecl *Method, SourceLocation lbrac, return false; } -bool Sema::CheckBlockCall(NamedDecl *NDecl, CallExpr *TheCall, - const FunctionProtoType *Proto) { +bool Sema::CheckPointerCall(NamedDecl *NDecl, CallExpr *TheCall, + const FunctionProtoType *Proto) { const VarDecl *V = dyn_cast<VarDecl>(NDecl); if (!V) return false; QualType Ty = V->getType(); - if (!Ty->isBlockPointerType()) + if (!Ty->isBlockPointerType() && !Ty->isFunctionPointerType()) return false; - VariadicCallType CallType = - Proto && Proto->isVariadic() ? VariadicBlock : VariadicDoesNotApply ; + VariadicCallType CallType; + if (!Proto || !Proto->isVariadic()) { + CallType = VariadicDoesNotApply; + } else if (Ty->isBlockPointerType()) { + CallType = VariadicBlock; + } else { // Ty->isFunctionPointerType() + CallType = VariadicFunction; + } unsigned NumProtoArgs = Proto ? Proto->getNumArgs() : 0; checkCall(NDecl, @@ -621,6 +865,23 @@ bool Sema::CheckBlockCall(NamedDecl *NDecl, CallExpr *TheCall, return false; } +/// Checks function calls when a FunctionDecl or a NamedDecl is not available, +/// such as function pointers returned from functions. +bool Sema::CheckOtherCall(CallExpr *TheCall, const FunctionProtoType *Proto) { + VariadicCallType CallType = getVariadicCallType(/*FDecl=*/0, Proto, + TheCall->getCallee()); + unsigned NumProtoArgs = Proto ? Proto->getNumArgs() : 0; + + checkCall(/*FDecl=*/0, + llvm::makeArrayRef<const Expr *>(TheCall->getArgs(), + TheCall->getNumArgs()), + NumProtoArgs, /*IsMemberFunction=*/false, + TheCall->getRParenLoc(), + TheCall->getCallee()->getSourceRange(), CallType); + + return false; +} + ExprResult Sema::SemaAtomicOpsOverloaded(ExprResult TheCallResult, AtomicExpr::AtomicOp Op) { CallExpr *TheCall = cast<CallExpr>(TheCallResult.get()); @@ -786,7 +1047,8 @@ ExprResult Sema::SemaAtomicOpsOverloaded(ExprResult TheCallResult, return ExprError(); } - if (!IsC11 && !AtomTy.isTriviallyCopyableType(Context)) { + if (!IsC11 && !AtomTy.isTriviallyCopyableType(Context) && + !AtomTy->isScalarType()) { // For GNU atomics, require a trivially-copyable type. This is not part of // the GNU atomics specification, but we enforce it for sanity. Diag(DRE->getLocStart(), diag::err_atomic_op_needs_trivial_copy) @@ -908,10 +1170,18 @@ ExprResult Sema::SemaAtomicOpsOverloaded(ExprResult TheCallResult, SubExprs.push_back(TheCall->getArg(3)); // Weak break; } + + AtomicExpr *AE = new (Context) AtomicExpr(TheCall->getCallee()->getLocStart(), + SubExprs, ResultType, Op, + TheCall->getRParenLoc()); + + if ((Op == AtomicExpr::AO__c11_atomic_load || + (Op == AtomicExpr::AO__c11_atomic_store)) && + Context.AtomicUsesUnsupportedLibcall(AE)) + Diag(AE->getLocStart(), diag::err_atomic_load_store_uses_lib) << + ((Op == AtomicExpr::AO__c11_atomic_load) ? 0 : 1); - return Owned(new (Context) AtomicExpr(TheCall->getCallee()->getLocStart(), - SubExprs, ResultType, Op, - TheCall->getRParenLoc())); + return Owned(AE); } @@ -1355,6 +1625,11 @@ bool Sema::SemaBuiltinVAStart(CallExpr *TheCall) { bool SecondArgIsLastNamedArgument = false; const Expr *Arg = TheCall->getArg(1)->IgnoreParenCasts(); + // These are valid if SecondArgIsLastNamedArgument is false after the next + // block. + QualType Type; + SourceLocation ParamLoc; + if (const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(Arg)) { if (const ParmVarDecl *PV = dyn_cast<ParmVarDecl>(DR->getDecl())) { // FIXME: This isn't correct for methods (results in bogus warning). @@ -1367,12 +1642,22 @@ bool Sema::SemaBuiltinVAStart(CallExpr *TheCall) { else LastArg = *(getCurMethodDecl()->param_end()-1); SecondArgIsLastNamedArgument = PV == LastArg; + + Type = PV->getType(); + ParamLoc = PV->getLocation(); } } if (!SecondArgIsLastNamedArgument) Diag(TheCall->getArg(1)->getLocStart(), diag::warn_second_parameter_of_va_start_not_last_named_argument); + else if (Type->isReferenceType()) { + Diag(Arg->getLocStart(), + diag::warn_va_start_of_reference_type_is_undefined); + Diag(ParamLoc, diag::note_parameter_type) << Type; + } + + TheCall->setType(Context.VoidTy); return false; } @@ -1464,8 +1749,8 @@ ExprResult Sema::SemaBuiltinShuffleVector(CallExpr *TheCall) { if (TheCall->getNumArgs() < 2) return ExprError(Diag(TheCall->getLocEnd(), diag::err_typecheck_call_too_few_args_at_least) - << 0 /*function call*/ << 2 << TheCall->getNumArgs() - << TheCall->getSourceRange()); + << 0 /*function call*/ << 2 << TheCall->getNumArgs() + << TheCall->getSourceRange()); // Determine which of the following types of shufflevector we're checking: // 1) unary, vector mask: (lhs, mask) @@ -1473,19 +1758,18 @@ ExprResult Sema::SemaBuiltinShuffleVector(CallExpr *TheCall) { // 3) binary, scalar mask: (lhs, rhs, index, ..., index) QualType resType = TheCall->getArg(0)->getType(); unsigned numElements = 0; - + if (!TheCall->getArg(0)->isTypeDependent() && !TheCall->getArg(1)->isTypeDependent()) { QualType LHSType = TheCall->getArg(0)->getType(); QualType RHSType = TheCall->getArg(1)->getType(); - - if (!LHSType->isVectorType() || !RHSType->isVectorType()) { - Diag(TheCall->getLocStart(), diag::err_shufflevector_non_vector) - << SourceRange(TheCall->getArg(0)->getLocStart(), - TheCall->getArg(1)->getLocEnd()); - return ExprError(); - } - + + if (!LHSType->isVectorType() || !RHSType->isVectorType()) + return ExprError(Diag(TheCall->getLocStart(), + diag::err_shufflevector_non_vector) + << SourceRange(TheCall->getArg(0)->getLocStart(), + TheCall->getArg(1)->getLocEnd())); + numElements = LHSType->getAs<VectorType>()->getNumElements(); unsigned numResElements = TheCall->getNumArgs() - 2; @@ -1493,18 +1777,17 @@ ExprResult Sema::SemaBuiltinShuffleVector(CallExpr *TheCall) { // with mask. If so, verify that RHS is an integer vector type with the // same number of elts as lhs. if (TheCall->getNumArgs() == 2) { - if (!RHSType->hasIntegerRepresentation() || + if (!RHSType->hasIntegerRepresentation() || RHSType->getAs<VectorType>()->getNumElements() != numElements) - Diag(TheCall->getLocStart(), diag::err_shufflevector_incompatible_vector) - << SourceRange(TheCall->getArg(1)->getLocStart(), - TheCall->getArg(1)->getLocEnd()); - numResElements = numElements; - } - else if (!Context.hasSameUnqualifiedType(LHSType, RHSType)) { - Diag(TheCall->getLocStart(), diag::err_shufflevector_incompatible_vector) - << SourceRange(TheCall->getArg(0)->getLocStart(), - TheCall->getArg(1)->getLocEnd()); - return ExprError(); + return ExprError(Diag(TheCall->getLocStart(), + diag::err_shufflevector_incompatible_vector) + << SourceRange(TheCall->getArg(1)->getLocStart(), + TheCall->getArg(1)->getLocEnd())); + } else if (!Context.hasSameUnqualifiedType(LHSType, RHSType)) { + return ExprError(Diag(TheCall->getLocStart(), + diag::err_shufflevector_incompatible_vector) + << SourceRange(TheCall->getArg(0)->getLocStart(), + TheCall->getArg(1)->getLocEnd())); } else if (numElements != numResElements) { QualType eltType = LHSType->getAs<VectorType>()->getElementType(); resType = Context.getVectorType(eltType, numResElements, @@ -1520,13 +1803,17 @@ ExprResult Sema::SemaBuiltinShuffleVector(CallExpr *TheCall) { llvm::APSInt Result(32); if (!TheCall->getArg(i)->isIntegerConstantExpr(Result, Context)) return ExprError(Diag(TheCall->getLocStart(), - diag::err_shufflevector_nonconstant_argument) - << TheCall->getArg(i)->getSourceRange()); + diag::err_shufflevector_nonconstant_argument) + << TheCall->getArg(i)->getSourceRange()); + + // Allow -1 which will be translated to undef in the IR. + if (Result.isSigned() && Result.isAllOnesValue()) + continue; if (Result.getActiveBits() > 64 || Result.getZExtValue() >= numElements*2) return ExprError(Diag(TheCall->getLocStart(), - diag::err_shufflevector_argument_too_large) - << TheCall->getArg(i)->getSourceRange()); + diag::err_shufflevector_argument_too_large) + << TheCall->getArg(i)->getSourceRange()); } SmallVector<Expr*, 32> exprs; @@ -1541,6 +1828,37 @@ ExprResult Sema::SemaBuiltinShuffleVector(CallExpr *TheCall) { TheCall->getRParenLoc())); } +/// SemaConvertVectorExpr - Handle __builtin_convertvector +ExprResult Sema::SemaConvertVectorExpr(Expr *E, TypeSourceInfo *TInfo, + SourceLocation BuiltinLoc, + SourceLocation RParenLoc) { + ExprValueKind VK = VK_RValue; + ExprObjectKind OK = OK_Ordinary; + QualType DstTy = TInfo->getType(); + QualType SrcTy = E->getType(); + + if (!SrcTy->isVectorType() && !SrcTy->isDependentType()) + return ExprError(Diag(BuiltinLoc, + diag::err_convertvector_non_vector) + << E->getSourceRange()); + if (!DstTy->isVectorType() && !DstTy->isDependentType()) + return ExprError(Diag(BuiltinLoc, + diag::err_convertvector_non_vector_type)); + + if (!SrcTy->isDependentType() && !DstTy->isDependentType()) { + unsigned SrcElts = SrcTy->getAs<VectorType>()->getNumElements(); + unsigned DstElts = DstTy->getAs<VectorType>()->getNumElements(); + if (SrcElts != DstElts) + return ExprError(Diag(BuiltinLoc, + diag::err_convertvector_incompatible_vector) + << E->getSourceRange()); + } + + return Owned(new (Context) ConvertVectorExpr(E, TInfo, DstTy, VK, OK, + BuiltinLoc, RParenLoc)); + +} + /// SemaBuiltinPrefetch - Handle __builtin_prefetch. // This is declared to take (const void*, ...) and can take two // optional constant int args. @@ -1642,28 +1960,36 @@ bool Sema::SemaBuiltinLongjmp(CallExpr *TheCall) { return false; } +namespace { +enum StringLiteralCheckType { + SLCT_NotALiteral, + SLCT_UncheckedLiteral, + SLCT_CheckedLiteral +}; +} + // Determine if an expression is a string literal or constant string. // If this function returns false on the arguments to a function expecting a // format string, we will usually need to emit a warning. // True string literals are then checked by CheckFormatString. -Sema::StringLiteralCheckType -Sema::checkFormatStringExpr(const Expr *E, ArrayRef<const Expr *> Args, - bool HasVAListArg, - unsigned format_idx, unsigned firstDataArg, - FormatStringType Type, VariadicCallType CallType, - bool inFunctionCall) { +static StringLiteralCheckType +checkFormatStringExpr(Sema &S, const Expr *E, ArrayRef<const Expr *> Args, + bool HasVAListArg, unsigned format_idx, + unsigned firstDataArg, Sema::FormatStringType Type, + Sema::VariadicCallType CallType, bool InFunctionCall, + llvm::SmallBitVector &CheckedVarArgs) { tryAgain: if (E->isTypeDependent() || E->isValueDependent()) return SLCT_NotALiteral; E = E->IgnoreParenCasts(); - if (E->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNotNull)) + if (E->isNullPointerConstant(S.Context, Expr::NPC_ValueDependentIsNotNull)) // Technically -Wformat-nonliteral does not warn about this case. // The behavior of printf and friends in this case is implementation // dependent. Ideally if the format string cannot be null then // it should have a 'nonnull' attribute in the function prototype. - return SLCT_CheckedLiteral; + return SLCT_UncheckedLiteral; switch (E->getStmtClass()) { case Stmt::BinaryConditionalOperatorClass: @@ -1673,15 +1999,15 @@ Sema::checkFormatStringExpr(const Expr *E, ArrayRef<const Expr *> Args, const AbstractConditionalOperator *C = cast<AbstractConditionalOperator>(E); StringLiteralCheckType Left = - checkFormatStringExpr(C->getTrueExpr(), Args, + checkFormatStringExpr(S, C->getTrueExpr(), Args, HasVAListArg, format_idx, firstDataArg, - Type, CallType, inFunctionCall); + Type, CallType, InFunctionCall, CheckedVarArgs); if (Left == SLCT_NotALiteral) return SLCT_NotALiteral; StringLiteralCheckType Right = - checkFormatStringExpr(C->getFalseExpr(), Args, + checkFormatStringExpr(S, C->getFalseExpr(), Args, HasVAListArg, format_idx, firstDataArg, - Type, CallType, inFunctionCall); + Type, CallType, InFunctionCall, CheckedVarArgs); return Left < Right ? Left : Right; } @@ -1712,15 +2038,15 @@ Sema::checkFormatStringExpr(const Expr *E, ArrayRef<const Expr *> Args, bool isConstant = false; QualType T = DR->getType(); - if (const ArrayType *AT = Context.getAsArrayType(T)) { - isConstant = AT->getElementType().isConstant(Context); + if (const ArrayType *AT = S.Context.getAsArrayType(T)) { + isConstant = AT->getElementType().isConstant(S.Context); } else if (const PointerType *PT = T->getAs<PointerType>()) { - isConstant = T.isConstant(Context) && - PT->getPointeeType().isConstant(Context); + isConstant = T.isConstant(S.Context) && + PT->getPointeeType().isConstant(S.Context); } else if (T->isObjCObjectPointerType()) { // In ObjC, there is usually no "const ObjectPointer" type, // so don't check if the pointee type is constant. - isConstant = T.isConstant(Context); + isConstant = T.isConstant(S.Context); } if (isConstant) { @@ -1730,10 +2056,10 @@ Sema::checkFormatStringExpr(const Expr *E, ArrayRef<const Expr *> Args, if (InitList->isStringLiteralInit()) Init = InitList->getInit(0)->IgnoreParenImpCasts(); } - return checkFormatStringExpr(Init, Args, + return checkFormatStringExpr(S, Init, Args, HasVAListArg, format_idx, firstDataArg, Type, CallType, - /*inFunctionCall*/false); + /*InFunctionCall*/false, CheckedVarArgs); } } @@ -1750,7 +2076,7 @@ Sema::checkFormatStringExpr(const Expr *E, ArrayRef<const Expr *> Args, // va_start(ap, fmt); // vprintf(fmt, ap); // Do NOT emit a warning about "fmt". // ... - // + // } if (HasVAListArg) { if (const ParmVarDecl *PV = dyn_cast<ParmVarDecl>(VD)) { if (const NamedDecl *ND = dyn_cast<NamedDecl>(PV->getDeclContext())) { @@ -1766,7 +2092,7 @@ Sema::checkFormatStringExpr(const Expr *E, ArrayRef<const Expr *> Args, // We also check if the formats are compatible. // We can't pass a 'scanf' string to a 'printf' function. if (PVIndex == PVFormat->getFormatIdx() && - Type == GetFormatStringType(PVFormat)) + Type == S.GetFormatStringType(PVFormat)) return SLCT_UncheckedLiteral; } } @@ -1788,24 +2114,46 @@ Sema::checkFormatStringExpr(const Expr *E, ArrayRef<const Expr *> Args, --ArgIndex; const Expr *Arg = CE->getArg(ArgIndex - 1); - return checkFormatStringExpr(Arg, Args, + return checkFormatStringExpr(S, Arg, Args, HasVAListArg, format_idx, firstDataArg, - Type, CallType, inFunctionCall); + Type, CallType, InFunctionCall, + CheckedVarArgs); } else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) { unsigned BuiltinID = FD->getBuiltinID(); if (BuiltinID == Builtin::BI__builtin___CFStringMakeConstantString || BuiltinID == Builtin::BI__builtin___NSStringMakeConstantString) { const Expr *Arg = CE->getArg(0); - return checkFormatStringExpr(Arg, Args, + return checkFormatStringExpr(S, Arg, Args, HasVAListArg, format_idx, firstDataArg, Type, CallType, - inFunctionCall); + InFunctionCall, CheckedVarArgs); } } } return SLCT_NotALiteral; } + + case Stmt::ObjCMessageExprClass: { + const ObjCMessageExpr *ME = cast<ObjCMessageExpr>(E); + if (const ObjCMethodDecl *MDecl = ME->getMethodDecl()) { + if (const NamedDecl *ND = dyn_cast<NamedDecl>(MDecl)) { + if (const FormatArgAttr *FA = ND->getAttr<FormatArgAttr>()) { + unsigned ArgIndex = FA->getFormatIdx(); + if (ArgIndex <= ME->getNumArgs()) { + const Expr *Arg = ME->getArg(ArgIndex-1); + return checkFormatStringExpr(S, Arg, Args, + HasVAListArg, format_idx, + firstDataArg, Type, CallType, + InFunctionCall, CheckedVarArgs); + } + } + } + } + + return SLCT_NotALiteral; + } + case Stmt::ObjCStringLiteralClass: case Stmt::StringLiteralClass: { const StringLiteral *StrE = NULL; @@ -1816,8 +2164,8 @@ Sema::checkFormatStringExpr(const Expr *E, ArrayRef<const Expr *> Args, StrE = cast<StringLiteral>(E); if (StrE) { - CheckFormatString(StrE, E, Args, HasVAListArg, format_idx, - firstDataArg, Type, inFunctionCall, CallType); + S.CheckFormatString(StrE, E, Args, HasVAListArg, format_idx, firstDataArg, + Type, InFunctionCall, CallType, CheckedVarArgs); return SLCT_CheckedLiteral; } @@ -1856,7 +2204,7 @@ Sema::CheckNonNullArguments(const NonNullAttr *NonNull, } Sema::FormatStringType Sema::GetFormatStringType(const FormatAttr *Format) { - return llvm::StringSwitch<FormatStringType>(Format->getType()) + return llvm::StringSwitch<FormatStringType>(Format->getType()->getName()) .Case("scanf", FST_Scanf) .Cases("printf", "printf0", FST_Printf) .Cases("NSString", "CFString", FST_NSString) @@ -1873,12 +2221,13 @@ bool Sema::CheckFormatArguments(const FormatAttr *Format, ArrayRef<const Expr *> Args, bool IsCXXMember, VariadicCallType CallType, - SourceLocation Loc, SourceRange Range) { + SourceLocation Loc, SourceRange Range, + llvm::SmallBitVector &CheckedVarArgs) { FormatStringInfo FSI; if (getFormatStringInfo(Format, IsCXXMember, &FSI)) return CheckFormatArguments(Args, FSI.HasVAListArg, FSI.FormatIdx, FSI.FirstDataArg, GetFormatStringType(Format), - CallType, Loc, Range); + CallType, Loc, Range, CheckedVarArgs); return false; } @@ -1886,7 +2235,8 @@ bool Sema::CheckFormatArguments(ArrayRef<const Expr *> Args, bool HasVAListArg, unsigned format_idx, unsigned firstDataArg, FormatStringType Type, VariadicCallType CallType, - SourceLocation Loc, SourceRange Range) { + SourceLocation Loc, SourceRange Range, + llvm::SmallBitVector &CheckedVarArgs) { // CHECK: printf/scanf-like function is called with no format string. if (format_idx >= Args.size()) { Diag(Loc, diag::warn_missing_format_string) << Range; @@ -1908,8 +2258,9 @@ bool Sema::CheckFormatArguments(ArrayRef<const Expr *> Args, // ObjC string uses the same format specifiers as C string, so we can use // the same format string checking logic for both ObjC and C strings. StringLiteralCheckType CT = - checkFormatStringExpr(OrigFormatExpr, Args, HasVAListArg, - format_idx, firstDataArg, Type, CallType); + checkFormatStringExpr(*this, OrigFormatExpr, Args, HasVAListArg, + format_idx, firstDataArg, Type, CallType, + /*IsFunctionCall*/true, CheckedVarArgs); if (CT != SLCT_NotALiteral) // Literal format string found, check done! return CT == SLCT_CheckedLiteral; @@ -1929,7 +2280,7 @@ bool Sema::CheckFormatArguments(ArrayRef<const Expr *> Args, // If there are no arguments specified, warn with -Wformat-security, otherwise // warn only with -Wformat-nonliteral. - if (Args.size() == format_idx+1) + if (Args.size() == firstDataArg) Diag(Args[format_idx]->getLocStart(), diag::warn_format_nonliteral_noargs) << OrigFormatExpr->getSourceRange(); @@ -1952,27 +2303,30 @@ protected: const bool HasVAListArg; ArrayRef<const Expr *> Args; unsigned FormatIdx; - llvm::BitVector CoveredArgs; + llvm::SmallBitVector CoveredArgs; bool usesPositionalArgs; bool atFirstArg; bool inFunctionCall; Sema::VariadicCallType CallType; + llvm::SmallBitVector &CheckedVarArgs; public: CheckFormatHandler(Sema &s, const StringLiteral *fexpr, const Expr *origFormatExpr, unsigned firstDataArg, unsigned numDataArgs, const char *beg, bool hasVAListArg, ArrayRef<const Expr *> Args, unsigned formatIdx, bool inFunctionCall, - Sema::VariadicCallType callType) + Sema::VariadicCallType callType, + llvm::SmallBitVector &CheckedVarArgs) : S(s), FExpr(fexpr), OrigFormatExpr(origFormatExpr), FirstDataArg(firstDataArg), NumDataArgs(numDataArgs), Beg(beg), HasVAListArg(hasVAListArg), Args(Args), FormatIdx(formatIdx), usesPositionalArgs(false), atFirstArg(true), - inFunctionCall(inFunctionCall), CallType(callType) { - CoveredArgs.resize(numDataArgs); - CoveredArgs.reset(); - } + inFunctionCall(inFunctionCall), CallType(callType), + CheckedVarArgs(CheckedVarArgs) { + CoveredArgs.resize(numDataArgs); + CoveredArgs.reset(); + } void DoneProcessing(); @@ -2361,10 +2715,12 @@ public: const char *beg, bool hasVAListArg, ArrayRef<const Expr *> Args, unsigned formatIdx, bool inFunctionCall, - Sema::VariadicCallType CallType) - : CheckFormatHandler(s, fexpr, origFormatExpr, firstDataArg, - numDataArgs, beg, hasVAListArg, Args, - formatIdx, inFunctionCall, CallType), ObjCContext(isObjC) + Sema::VariadicCallType CallType, + llvm::SmallBitVector &CheckedVarArgs) + : CheckFormatHandler(s, fexpr, origFormatExpr, firstDataArg, + numDataArgs, beg, hasVAListArg, Args, + formatIdx, inFunctionCall, CallType, CheckedVarArgs), + ObjCContext(isObjC) {} @@ -2790,7 +3146,15 @@ CheckPrintfHandler::checkFormatExpr(const analyze_printf::PrintfSpecifier &FS, // 'unichar' is defined as a typedef of unsigned short, but we should // prefer using the typedef if it is visible. IntendedTy = S.Context.UnsignedShortTy; - + + // While we are here, check if the value is an IntegerLiteral that happens + // to be within the valid range. + if (const IntegerLiteral *IL = dyn_cast<IntegerLiteral>(E)) { + const llvm::APInt &V = IL->getValue(); + if (V.getActiveBits() <= S.Context.getTypeSize(IntendedTy)) + return true; + } + LookupResult Result(S, &S.Context.Idents.get("unichar"), E->getLocStart(), Sema::LookupOrdinaryName); if (S.LookupName(Result, S.getCurScope())) { @@ -2918,15 +3282,20 @@ CheckPrintfHandler::checkFormatExpr(const analyze_printf::PrintfSpecifier &FS, // Since the warning for passing non-POD types to variadic functions // was deferred until now, we emit a warning for non-POD // arguments here. - if (S.isValidVarArgType(ExprTy) == Sema::VAK_Invalid) { - unsigned DiagKind; - if (ExprTy->isObjCObjectType()) - DiagKind = diag::err_cannot_pass_objc_interface_to_vararg_format; - else - DiagKind = diag::warn_non_pod_vararg_with_format_string; + switch (S.isValidVarArgType(ExprTy)) { + case Sema::VAK_Valid: + case Sema::VAK_ValidInCXX11: + EmitFormatDiagnostic( + S.PDiag(diag::warn_printf_conversion_argument_type_mismatch) + << AT.getRepresentativeTypeName(S.Context) << ExprTy + << CSR + << E->getSourceRange(), + E->getLocStart(), /*IsStringLocation*/false, CSR); + break; + case Sema::VAK_Undefined: EmitFormatDiagnostic( - S.PDiag(DiagKind) + S.PDiag(diag::warn_non_pod_vararg_with_format_string) << S.getLangOpts().CPlusPlus11 << ExprTy << CallType @@ -2934,15 +3303,33 @@ CheckPrintfHandler::checkFormatExpr(const analyze_printf::PrintfSpecifier &FS, << CSR << E->getSourceRange(), E->getLocStart(), /*IsStringLocation*/false, CSR); - checkForCStrMembers(AT, E, CSR); - } else - EmitFormatDiagnostic( - S.PDiag(diag::warn_printf_conversion_argument_type_mismatch) - << AT.getRepresentativeTypeName(S.Context) << ExprTy - << CSR - << E->getSourceRange(), - E->getLocStart(), /*IsStringLocation*/false, CSR); + break; + + case Sema::VAK_Invalid: + if (ExprTy->isObjCObjectType()) + EmitFormatDiagnostic( + S.PDiag(diag::err_cannot_pass_objc_interface_to_vararg_format) + << S.getLangOpts().CPlusPlus11 + << ExprTy + << CallType + << AT.getRepresentativeTypeName(S.Context) + << CSR + << E->getSourceRange(), + E->getLocStart(), /*IsStringLocation*/false, CSR); + else + // FIXME: If this is an initializer list, suggest removing the braces + // or inserting a cast to the target type. + S.Diag(E->getLocStart(), diag::err_cannot_pass_to_vararg_format) + << isa<InitListExpr>(E) << ExprTy << CallType + << AT.getRepresentativeTypeName(S.Context) + << E->getSourceRange(); + break; + } + + assert(FirstDataArg + FS.getArgIndex() < CheckedVarArgs.size() && + "format string specifier index out of range"); + CheckedVarArgs[FirstDataArg + FS.getArgIndex()] = true; } return true; @@ -2958,10 +3345,12 @@ public: unsigned numDataArgs, const char *beg, bool hasVAListArg, ArrayRef<const Expr *> Args, unsigned formatIdx, bool inFunctionCall, - Sema::VariadicCallType CallType) - : CheckFormatHandler(s, fexpr, origFormatExpr, firstDataArg, - numDataArgs, beg, hasVAListArg, - Args, formatIdx, inFunctionCall, CallType) + Sema::VariadicCallType CallType, + llvm::SmallBitVector &CheckedVarArgs) + : CheckFormatHandler(s, fexpr, origFormatExpr, firstDataArg, + numDataArgs, beg, hasVAListArg, + Args, formatIdx, inFunctionCall, CallType, + CheckedVarArgs) {} bool HandleScanfSpecifier(const analyze_scanf::ScanfSpecifier &FS, @@ -3116,7 +3505,8 @@ void Sema::CheckFormatString(const StringLiteral *FExpr, ArrayRef<const Expr *> Args, bool HasVAListArg, unsigned format_idx, unsigned firstDataArg, FormatStringType Type, - bool inFunctionCall, VariadicCallType CallType) { + bool inFunctionCall, VariadicCallType CallType, + llvm::SmallBitVector &CheckedVarArgs) { // CHECK: is the format string a wide literal? if (!FExpr->isAscii() && !FExpr->isUTF8()) { @@ -3146,7 +3536,7 @@ void Sema::CheckFormatString(const StringLiteral *FExpr, CheckPrintfHandler H(*this, FExpr, OrigFormatExpr, firstDataArg, numDataArgs, (Type == FST_NSString), Str, HasVAListArg, Args, format_idx, - inFunctionCall, CallType); + inFunctionCall, CallType, CheckedVarArgs); if (!analyze_format_string::ParsePrintfString(H, Str, Str + StrLen, getLangOpts(), @@ -3155,7 +3545,7 @@ void Sema::CheckFormatString(const StringLiteral *FExpr, } else if (Type == FST_Scanf) { CheckScanfHandler H(*this, FExpr, OrigFormatExpr, firstDataArg, numDataArgs, Str, HasVAListArg, Args, format_idx, - inFunctionCall, CallType); + inFunctionCall, CallType, CheckedVarArgs); if (!analyze_format_string::ParseScanfString(H, Str, Str + StrLen, getLangOpts(), @@ -3654,7 +4044,7 @@ Sema::CheckReturnStackAddr(Expr *RetValExp, QualType lhsType, static Expr *EvalAddr(Expr *E, SmallVectorImpl<DeclRefExpr *> &refVars, Decl *ParentDecl) { if (E->isTypeDependent()) - return NULL; + return NULL; // We should only be called for evaluating pointer expressions. assert((E->getType()->isAnyPointerType() || @@ -4096,6 +4486,13 @@ static IntRange GetValueRange(ASTContext &C, APValue &result, QualType Ty, return IntRange(MaxWidth, Ty->isUnsignedIntegerOrEnumerationType()); } +static QualType GetExprType(Expr *E) { + QualType Ty = E->getType(); + if (const AtomicType *AtomicRHS = Ty->getAs<AtomicType>()) + Ty = AtomicRHS->getValueType(); + return Ty; +} + /// Pseudo-evaluate the given integer expression, estimating the /// range of values it might take. /// @@ -4106,7 +4503,7 @@ static IntRange GetExprRange(ASTContext &C, Expr *E, unsigned MaxWidth) { // Try a full evaluation first. Expr::EvalResult result; if (E->EvaluateAsRValue(result, C)) - return GetValueRange(C, result.Val, E->getType(), MaxWidth); + return GetValueRange(C, result.Val, GetExprType(E), MaxWidth); // I think we only want to look through implicit casts here; if the // user has an explicit widening cast, we should treat the value as @@ -4115,7 +4512,7 @@ static IntRange GetExprRange(ASTContext &C, Expr *E, unsigned MaxWidth) { if (CE->getCastKind() == CK_NoOp || CE->getCastKind() == CK_LValueToRValue) return GetExprRange(C, CE->getSubExpr(), MaxWidth); - IntRange OutputTypeRange = IntRange::forValueOfType(C, CE->getType()); + IntRange OutputTypeRange = IntRange::forValueOfType(C, GetExprType(CE)); bool isIntegerCast = (CE->getCastKind() == CK_IntegralCast); @@ -4175,7 +4572,7 @@ static IntRange GetExprRange(ASTContext &C, Expr *E, unsigned MaxWidth) { case BO_XorAssign: case BO_OrAssign: // TODO: bitfields? - return IntRange::forValueOfType(C, E->getType()); + return IntRange::forValueOfType(C, GetExprType(E)); // Simple assignments just pass through the RHS, which will have // been coerced to the LHS type. @@ -4186,7 +4583,7 @@ static IntRange GetExprRange(ASTContext &C, Expr *E, unsigned MaxWidth) { // Operations with opaque sources are black-listed. case BO_PtrMemD: case BO_PtrMemI: - return IntRange::forValueOfType(C, E->getType()); + return IntRange::forValueOfType(C, GetExprType(E)); // Bitwise-and uses the *infinum* of the two source ranges. case BO_And: @@ -4201,14 +4598,14 @@ static IntRange GetExprRange(ASTContext &C, Expr *E, unsigned MaxWidth) { if (IntegerLiteral *I = dyn_cast<IntegerLiteral>(BO->getLHS()->IgnoreParenCasts())) { if (I->getValue() == 1) { - IntRange R = IntRange::forValueOfType(C, E->getType()); + IntRange R = IntRange::forValueOfType(C, GetExprType(E)); return IntRange(R.Width, /*NonNegative*/ true); } } // fallthrough case BO_ShlAssign: - return IntRange::forValueOfType(C, E->getType()); + return IntRange::forValueOfType(C, GetExprType(E)); // Right shift by a constant can narrow its left argument. case BO_Shr: @@ -4237,14 +4634,14 @@ static IntRange GetExprRange(ASTContext &C, Expr *E, unsigned MaxWidth) { // Black-list pointer subtractions. case BO_Sub: if (BO->getLHS()->getType()->isPointerType()) - return IntRange::forValueOfType(C, E->getType()); + return IntRange::forValueOfType(C, GetExprType(E)); break; // The width of a division result is mostly determined by the size // of the LHS. case BO_Div: { // Don't 'pre-truncate' the operands. - unsigned opWidth = C.getIntWidth(E->getType()); + unsigned opWidth = C.getIntWidth(GetExprType(E)); IntRange L = GetExprRange(C, BO->getLHS(), opWidth); // If the divisor is constant, use that. @@ -4267,7 +4664,7 @@ static IntRange GetExprRange(ASTContext &C, Expr *E, unsigned MaxWidth) { // either side. case BO_Rem: { // Don't 'pre-truncate' the operands. - unsigned opWidth = C.getIntWidth(E->getType()); + unsigned opWidth = C.getIntWidth(GetExprType(E)); IntRange L = GetExprRange(C, BO->getLHS(), opWidth); IntRange R = GetExprRange(C, BO->getRHS(), opWidth); @@ -4300,26 +4697,25 @@ static IntRange GetExprRange(ASTContext &C, Expr *E, unsigned MaxWidth) { // Operations with opaque sources are black-listed. case UO_Deref: case UO_AddrOf: // should be impossible - return IntRange::forValueOfType(C, E->getType()); + return IntRange::forValueOfType(C, GetExprType(E)); default: return GetExprRange(C, UO->getSubExpr(), MaxWidth); } } - - if (dyn_cast<OffsetOfExpr>(E)) { - IntRange::forValueOfType(C, E->getType()); - } + + if (OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E)) + return GetExprRange(C, OVE->getSourceExpr(), MaxWidth); if (FieldDecl *BitField = E->getSourceBitField()) return IntRange(BitField->getBitWidthValue(C), BitField->getType()->isUnsignedIntegerOrEnumerationType()); - return IntRange::forValueOfType(C, E->getType()); + return IntRange::forValueOfType(C, GetExprType(E)); } static IntRange GetExprRange(ASTContext &C, Expr *E) { - return GetExprRange(C, E, C.getIntWidth(E->getType())); + return GetExprRange(C, E, C.getIntWidth(GetExprType(E))); } /// Checks whether the given value, which currently has the given @@ -4390,6 +4786,10 @@ static bool HasEnumType(Expr *E) { } static void CheckTrivialUnsignedComparison(Sema &S, BinaryOperator *E) { + // Disable warning in template instantiations. + if (!S.ActiveTemplateInstantiations.empty()) + return; + BinaryOperatorKind op = E->getOpcode(); if (E->isValueDependent()) return; @@ -4417,6 +4817,10 @@ static void DiagnoseOutOfRangeComparison(Sema &S, BinaryOperator *E, Expr *Constant, Expr *Other, llvm::APSInt Value, bool RhsConstant) { + // Disable warning in template instantiations. + if (!S.ActiveTemplateInstantiations.empty()) + return; + // 0 values are handled later by CheckTrivialUnsignedComparison(). if (Value == 0) return; @@ -4736,8 +5140,16 @@ void DiagnoseFloatingLiteralImpCast(Sema &S, FloatingLiteral *FL, QualType T, == llvm::APFloat::opOK && isExact) return; + // FIXME: Force the precision of the source value down so we don't print + // digits which are usually useless (we don't really care here if we + // truncate a digit by accident in edge cases). Ideally, APFloat::toString + // would automatically print the shortest representation, but it's a bit + // tricky to implement. SmallString<16> PrettySourceValue; - Value.toString(PrettySourceValue); + unsigned precision = llvm::APFloat::semanticsPrecision(Value.getSemantics()); + precision = (precision * 59 + 195) / 196; + Value.toString(PrettySourceValue, precision); + SmallString<16> PrettyTargetValue; if (T->isSpecificBuiltinType(BuiltinType::Bool)) PrettyTargetValue = IntegerValue == 0 ? "false" : "true"; @@ -4843,7 +5255,7 @@ void CheckImplicitConversion(Sema &S, Expr *E, QualType T, << FixItHint::CreateInsertion(E->getExprLoc(), "&"); QualType ReturnType; UnresolvedSet<4> NonTemplateOverloads; - S.isExprCallable(*E, ReturnType, NonTemplateOverloads); + S.tryExprAsCall(*E, ReturnType, NonTemplateOverloads); if (!ReturnType.isNull() && ReturnType->isSpecificBuiltinType(BuiltinType::Bool)) S.Diag(E->getExprLoc(), diag::note_function_to_bool_call) @@ -4966,7 +5378,8 @@ void CheckImplicitConversion(Sema &S, Expr *E, QualType T, if (!Loc.isMacroID() || CC.isMacroID()) S.Diag(Loc, diag::warn_impcast_null_pointer_to_integer) << T << clang::SourceRange(CC) - << FixItHint::CreateReplacement(Loc, S.getFixItZeroLiteralForType(T)); + << FixItHint::CreateReplacement(Loc, + S.getFixItZeroLiteralForType(T, Loc)); } if (!Source->isIntegerType() || !Target->isIntegerType()) @@ -5133,7 +5546,15 @@ void AnalyzeImplicitConversions(Sema &S, Expr *OrigE, SourceLocation CC) { CheckImplicitConversion(S, E, T, CC); // Now continue drilling into this expression. - + + if (PseudoObjectExpr * POE = dyn_cast<PseudoObjectExpr>(E)) { + if (POE->getResultExpr()) + E = POE->getResultExpr(); + } + + if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E)) + return AnalyzeImplicitConversions(S, OVE->getSourceExpr(), CC); + // Skip past explicit casts. if (isa<ExplicitCastExpr>(E)) { E = cast<ExplicitCastExpr>(E)->getSubExpr()->IgnoreParenImpCasts(); @@ -5206,16 +5627,16 @@ void Sema::CheckImplicitConversions(Expr *E, SourceLocation CC) { /// Diagnose when expression is an integer constant expression and its evaluation /// results in integer overflow void Sema::CheckForIntOverflow (Expr *E) { - if (isa<BinaryOperator>(E->IgnoreParens())) { - llvm::SmallVector<PartialDiagnosticAt, 4> Diags; - E->EvaluateForOverflow(Context, &Diags); - } + if (isa<BinaryOperator>(E->IgnoreParens())) + E->EvaluateForOverflow(Context); } namespace { /// \brief Visitor for expressions which looks for unsequenced operations on the /// same object. class SequenceChecker : public EvaluatedExprVisitor<SequenceChecker> { + typedef EvaluatedExprVisitor<SequenceChecker> Base; + /// \brief A tree of sequenced regions within an expression. Two regions are /// unsequenced if one is an ancestor or a descendent of the other. When we /// finish processing an expression with sequencing, such as a comma @@ -5227,7 +5648,7 @@ class SequenceChecker : public EvaluatedExprVisitor<SequenceChecker> { unsigned Parent : 31; bool Merged : 1; }; - llvm::SmallVector<Value, 8> Values; + SmallVector<Value, 8> Values; public: /// \brief A region within an expression which may be sequenced with respect @@ -5289,7 +5710,7 @@ class SequenceChecker : public EvaluatedExprVisitor<SequenceChecker> { /// A read of an object. Multiple unsequenced reads are OK. UK_Use, /// A modification of an object which is sequenced before the value - /// computation of the expression, such as ++n. + /// computation of the expression, such as ++n in C++. UK_ModAsValue, /// A modification of an object which is not sequenced before the value /// computation of the expression, such as n++. @@ -5321,10 +5742,10 @@ class SequenceChecker : public EvaluatedExprVisitor<SequenceChecker> { SequenceTree::Seq Region; /// Filled in with declarations which were modified as a side-effect /// (that is, post-increment operations). - llvm::SmallVectorImpl<std::pair<Object, Usage> > *ModAsSideEffect; + SmallVectorImpl<std::pair<Object, Usage> > *ModAsSideEffect; /// Expressions to check later. We defer checking these to reduce /// stack usage. - llvm::SmallVectorImpl<Expr*> &WorkList; + SmallVectorImpl<Expr *> &WorkList; /// RAII object wrapping the visitation of a sequenced subexpression of an /// expression. At the end of this process, the side-effects of the evaluation @@ -5347,10 +5768,39 @@ class SequenceChecker : public EvaluatedExprVisitor<SequenceChecker> { } SequenceChecker &Self; - llvm::SmallVector<std::pair<Object, Usage>, 4> ModAsSideEffect; - llvm::SmallVectorImpl<std::pair<Object, Usage> > *OldModAsSideEffect; + SmallVector<std::pair<Object, Usage>, 4> ModAsSideEffect; + SmallVectorImpl<std::pair<Object, Usage> > *OldModAsSideEffect; }; + /// RAII object wrapping the visitation of a subexpression which we might + /// choose to evaluate as a constant. If any subexpression is evaluated and + /// found to be non-constant, this allows us to suppress the evaluation of + /// the outer expression. + class EvaluationTracker { + public: + EvaluationTracker(SequenceChecker &Self) + : Self(Self), Prev(Self.EvalTracker), EvalOK(true) { + Self.EvalTracker = this; + } + ~EvaluationTracker() { + Self.EvalTracker = Prev; + if (Prev) + Prev->EvalOK &= EvalOK; + } + + bool evaluate(const Expr *E, bool &Result) { + if (!EvalOK || E->isValueDependent()) + return false; + EvalOK = E->EvaluateAsBooleanCondition(Result, Self.SemaRef.Context); + return EvalOK; + } + + private: + SequenceChecker &Self; + EvaluationTracker *Prev; + bool EvalOK; + } *EvalTracker; + /// \brief Find the object which is produced by the specified expression, /// if any. Object getObject(Expr *E, bool Mod) const { @@ -5429,10 +5879,9 @@ class SequenceChecker : public EvaluatedExprVisitor<SequenceChecker> { } public: - SequenceChecker(Sema &S, Expr *E, - llvm::SmallVectorImpl<Expr*> &WorkList) - : EvaluatedExprVisitor<SequenceChecker>(S.Context), SemaRef(S), - Region(Tree.root()), ModAsSideEffect(0), WorkList(WorkList) { + SequenceChecker(Sema &S, Expr *E, SmallVectorImpl<Expr *> &WorkList) + : Base(S.Context), SemaRef(S), Region(Tree.root()), ModAsSideEffect(0), + WorkList(WorkList), EvalTracker(0) { Visit(E); } @@ -5442,7 +5891,7 @@ public: void VisitExpr(Expr *E) { // By default, just recurse to evaluated subexpressions. - EvaluatedExprVisitor<SequenceChecker>::VisitStmt(E); + Base::VisitStmt(E); } void VisitCastExpr(CastExpr *E) { @@ -5509,7 +5958,12 @@ public: Visit(BO->getRHS()); - notePostMod(O, BO, UK_ModAsValue); + // C++11 [expr.ass]p1: + // the assignment is sequenced [...] before the value computation of the + // assignment expression. + // C11 6.5.16/3 has no such rule. + notePostMod(O, BO, SemaRef.getLangOpts().CPlusPlus ? UK_ModAsValue + : UK_ModAsSideEffect); } void VisitCompoundAssignOperator(CompoundAssignOperator *CAO) { VisitBinAssign(CAO); @@ -5524,7 +5978,10 @@ public: notePreMod(O, UO); Visit(UO->getSubExpr()); - notePostMod(O, UO, UK_ModAsValue); + // C++11 [expr.pre.incr]p1: + // the expression ++x is equivalent to x+=1 + notePostMod(O, UO, SemaRef.getLangOpts().CPlusPlus ? UK_ModAsValue + : UK_ModAsSideEffect); } void VisitUnaryPostInc(UnaryOperator *UO) { VisitUnaryPostIncDec(UO); } @@ -5545,14 +6002,14 @@ public: // value computation of the RHS, and hence before the value computation // of the '&&' itself, unless the LHS evaluates to zero. We treat them // as if they were unconditionally sequenced. + EvaluationTracker Eval(*this); { SequencedSubexpression Sequenced(*this); Visit(BO->getLHS()); } bool Result; - if (!BO->getLHS()->isValueDependent() && - BO->getLHS()->EvaluateAsBooleanCondition(Result, SemaRef.Context)) { + if (Eval.evaluate(BO->getLHS(), Result)) { if (!Result) Visit(BO->getRHS()); } else { @@ -5566,14 +6023,14 @@ public: } } void VisitBinLAnd(BinaryOperator *BO) { + EvaluationTracker Eval(*this); { SequencedSubexpression Sequenced(*this); Visit(BO->getLHS()); } bool Result; - if (!BO->getLHS()->isValueDependent() && - BO->getLHS()->EvaluateAsBooleanCondition(Result, SemaRef.Context)) { + if (Eval.evaluate(BO->getLHS(), Result)) { if (Result) Visit(BO->getRHS()); } else { @@ -5584,12 +6041,14 @@ public: // Only visit the condition, unless we can be sure which subexpression will // be chosen. void VisitAbstractConditionalOperator(AbstractConditionalOperator *CO) { - SequencedSubexpression Sequenced(*this); - Visit(CO->getCond()); + EvaluationTracker Eval(*this); + { + SequencedSubexpression Sequenced(*this); + Visit(CO->getCond()); + } bool Result; - if (!CO->getCond()->isValueDependent() && - CO->getCond()->EvaluateAsBooleanCondition(Result, SemaRef.Context)) + if (Eval.evaluate(CO->getCond(), Result)) Visit(Result ? CO->getTrueExpr() : CO->getFalseExpr()); else { WorkList.push_back(CO->getTrueExpr()); @@ -5597,12 +6056,28 @@ public: } } + void VisitCallExpr(CallExpr *CE) { + // C++11 [intro.execution]p15: + // When calling a function [...], every value computation and side effect + // associated with any argument expression, or with the postfix expression + // designating the called function, is sequenced before execution of every + // expression or statement in the body of the function [and thus before + // the value computation of its result]. + SequencedSubexpression Sequenced(*this); + Base::VisitCallExpr(CE); + + // FIXME: CXXNewExpr and CXXDeleteExpr implicitly call functions. + } + void VisitCXXConstructExpr(CXXConstructExpr *CCE) { + // This is a call, so all subexpressions are sequenced before the result. + SequencedSubexpression Sequenced(*this); + if (!CCE->isListInitialization()) return VisitExpr(CCE); // In C++11, list initializations are sequenced. - llvm::SmallVector<SequenceTree::Seq, 32> Elts; + SmallVector<SequenceTree::Seq, 32> Elts; SequenceTree::Seq Parent = Region; for (CXXConstructExpr::arg_iterator I = CCE->arg_begin(), E = CCE->arg_end(); @@ -5623,7 +6098,7 @@ public: return VisitExpr(ILE); // In C++11, list initializations are sequenced. - llvm::SmallVector<SequenceTree::Seq, 32> Elts; + SmallVector<SequenceTree::Seq, 32> Elts; SequenceTree::Seq Parent = Region; for (unsigned I = 0; I < ILE->getNumInits(); ++I) { Expr *E = ILE->getInit(I); @@ -5642,11 +6117,10 @@ public: } void Sema::CheckUnsequencedOperations(Expr *E) { - llvm::SmallVector<Expr*, 8> WorkList; + SmallVector<Expr *, 8> WorkList; WorkList.push_back(E); while (!WorkList.empty()) { - Expr *Item = WorkList.back(); - WorkList.pop_back(); + Expr *Item = WorkList.pop_back_val(); SequenceChecker(*this, Item, WorkList); } } @@ -5670,7 +6144,8 @@ void Sema::CheckBitFieldInitialization(SourceLocation InitLoc, /// takes care of any checks that cannot be performed on the /// declaration itself, e.g., that the types of each of the function /// parameters are complete. -bool Sema::CheckParmsForFunctionDef(ParmVarDecl **P, ParmVarDecl **PEnd, +bool Sema::CheckParmsForFunctionDef(ParmVarDecl *const *P, + ParmVarDecl *const *PEnd, bool CheckParameterNames) { bool HasInvalidParm = false; for (; P != PEnd; ++P) { @@ -5711,6 +6186,15 @@ bool Sema::CheckParmsForFunctionDef(ParmVarDecl **P, ParmVarDecl **PEnd, } PType= AT->getElementType(); } + + // MSVC destroys objects passed by value in the callee. Therefore a + // function definition which takes such a parameter must be able to call the + // object's destructor. + if (getLangOpts().CPlusPlus && + Context.getTargetInfo().getCXXABI().isArgumentDestroyedByCallee()) { + if (const RecordType *RT = Param->getType()->getAs<RecordType>()) + FinalizeVarWithDestructor(Param, RT); + } } return HasInvalidParm; @@ -5892,7 +6376,7 @@ void Sema::CheckArrayAccess(const Expr *BaseExpr, const Expr *IndexExpr, if (SourceMgr.isInSystemHeader(RBracketLoc)) { SourceLocation IndexLoc = SourceMgr.getSpellingLoc( IndexExpr->getLocStart()); - if (SourceMgr.isFromSameFile(RBracketLoc, IndexLoc)) + if (SourceMgr.isWrittenInSameFile(RBracketLoc, IndexLoc)) return; } } |