diff options
author | Will Dietz <wdietz2@illinois.edu> | 2013-01-18 11:30:38 +0000 |
---|---|---|
committer | Will Dietz <wdietz2@illinois.edu> | 2013-01-18 11:30:38 +0000 |
commit | 4f45bc099f2665bc6e4bcbb169aa452390dbf3fe (patch) | |
tree | 67a70eeaf5da4ec49baf3ce37ac44bb15eb1c9fb /lib | |
parent | c79afdae8a2e12d1e8f27a2ae0a43dfca3b8283b (diff) |
[ubsan] Add support for -fsanitize-blacklist
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@172808 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Basic/LangOptions.cpp | 8 | ||||
-rw-r--r-- | lib/Basic/Targets.cpp | 2 | ||||
-rw-r--r-- | lib/CodeGen/BackendUtil.cpp | 16 | ||||
-rw-r--r-- | lib/CodeGen/CGBuiltin.cpp | 2 | ||||
-rw-r--r-- | lib/CodeGen/CGDeclCXX.cpp | 2 | ||||
-rw-r--r-- | lib/CodeGen/CGExpr.cpp | 13 | ||||
-rw-r--r-- | lib/CodeGen/CGExprScalar.cpp | 49 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenFunction.cpp | 18 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenFunction.h | 5 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenModule.cpp | 15 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenModule.h | 15 | ||||
-rw-r--r-- | lib/Frontend/CompilerInvocation.cpp | 2 | ||||
-rw-r--r-- | lib/Lex/PPMacroExpansion.cpp | 6 | ||||
-rw-r--r-- | lib/Serialization/ASTReader.cpp | 2 | ||||
-rw-r--r-- | lib/Serialization/ASTWriter.cpp | 2 |
15 files changed, 94 insertions, 63 deletions
diff --git a/lib/Basic/LangOptions.cpp b/lib/Basic/LangOptions.cpp index 991992a477..e18d9256f5 100644 --- a/lib/Basic/LangOptions.cpp +++ b/lib/Basic/LangOptions.cpp @@ -14,10 +14,14 @@ using namespace clang; +const SanitizerOptions SanitizerOptions::Disabled = {}; + LangOptions::LangOptions() { #define LANGOPT(Name, Bits, Default, Description) Name = Default; #define ENUM_LANGOPT(Name, Type, Bits, Default, Description) set##Name(Default); #include "clang/Basic/LangOptions.def" + + Sanitize = SanitizerOptions::Disabled; } void LangOptions::resetNonModularOptions() { @@ -26,7 +30,9 @@ void LangOptions::resetNonModularOptions() { #define BENIGN_ENUM_LANGOPT(Name, Type, Bits, Default, Description) \ Name = Default; #include "clang/Basic/LangOptions.def" - + + Sanitize = SanitizerOptions::Disabled; + CurrentModule.clear(); } diff --git a/lib/Basic/Targets.cpp b/lib/Basic/Targets.cpp index 9f7e97cf7f..8e45804bff 100644 --- a/lib/Basic/Targets.cpp +++ b/lib/Basic/Targets.cpp @@ -94,7 +94,7 @@ static void getDarwinDefines(MacroBuilder &Builder, const LangOptions &Opts, Builder.defineMacro("OBJC_NEW_PROPERTIES"); // AddressSanitizer doesn't play well with source fortification, which is on // by default on Darwin. - if (Opts.SanitizeAddress) Builder.defineMacro("_FORTIFY_SOURCE", "0"); + if (Opts.Sanitize.Address) Builder.defineMacro("_FORTIFY_SOURCE", "0"); if (!Opts.ObjCAutoRefCount) { // __weak is always defined, for use in blocks and with objc pointers. diff --git a/lib/CodeGen/BackendUtil.cpp b/lib/CodeGen/BackendUtil.cpp index d343207545..8a3ee398cd 100644 --- a/lib/CodeGen/BackendUtil.cpp +++ b/lib/CodeGen/BackendUtil.cpp @@ -164,11 +164,11 @@ static void addAddressSanitizerPasses(const PassManagerBuilder &Builder, static_cast<const PassManagerBuilderWrapper&>(Builder); const CodeGenOptions &CGOpts = BuilderWrapper.getCGOpts(); const LangOptions &LangOpts = BuilderWrapper.getLangOpts(); - PM.add(createAddressSanitizerFunctionPass(LangOpts.SanitizeInitOrder, - LangOpts.SanitizeUseAfterReturn, - LangOpts.SanitizeUseAfterScope, + PM.add(createAddressSanitizerFunctionPass(LangOpts.Sanitize.InitOrder, + LangOpts.Sanitize.UseAfterReturn, + LangOpts.Sanitize.UseAfterScope, CGOpts.SanitizerBlacklistFile)); - PM.add(createAddressSanitizerModulePass(LangOpts.SanitizeInitOrder, + PM.add(createAddressSanitizerModulePass(LangOpts.Sanitize.InitOrder, CGOpts.SanitizerBlacklistFile)); } @@ -218,28 +218,28 @@ void EmitAssemblyHelper::CreatePasses(TargetMachine *TM) { addObjCARCOptPass); } - if (LangOpts.SanitizeBounds) { + if (LangOpts.Sanitize.Bounds) { PMBuilder.addExtension(PassManagerBuilder::EP_ScalarOptimizerLate, addBoundsCheckingPass); PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0, addBoundsCheckingPass); } - if (LangOpts.SanitizeAddress) { + if (LangOpts.Sanitize.Address) { PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast, addAddressSanitizerPasses); PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0, addAddressSanitizerPasses); } - if (LangOpts.SanitizeMemory) { + if (LangOpts.Sanitize.Memory) { PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast, addMemorySanitizerPass); PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0, addMemorySanitizerPass); } - if (LangOpts.SanitizeThread) { + if (LangOpts.Sanitize.Thread) { PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast, addThreadSanitizerPass); PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0, diff --git a/lib/CodeGen/CGBuiltin.cpp b/lib/CodeGen/CGBuiltin.cpp index 6678ebe71c..9e09131a53 100644 --- a/lib/CodeGen/CGBuiltin.cpp +++ b/lib/CodeGen/CGBuiltin.cpp @@ -436,7 +436,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD, return RValue::get(Builder.CreateCall(F)); } case Builtin::BI__builtin_unreachable: { - if (getLangOpts().SanitizeUnreachable) + if (SanOpts->Unreachable) EmitCheck(Builder.getFalse(), "builtin_unreachable", EmitCheckSourceLocation(E->getExprLoc()), ArrayRef<llvm::Value *>(), CRK_Unrecoverable); diff --git a/lib/CodeGen/CGDeclCXX.cpp b/lib/CodeGen/CGDeclCXX.cpp index 11f1609a3b..f9d8199bb8 100644 --- a/lib/CodeGen/CGDeclCXX.cpp +++ b/lib/CodeGen/CGDeclCXX.cpp @@ -232,7 +232,7 @@ CreateGlobalInitOrDestructFunction(CodeGenModule &CGM, if (!CGM.getLangOpts().Exceptions) Fn->setDoesNotThrow(); - if (CGM.getLangOpts().SanitizeAddress) + if (CGM.getSanOpts().Address) Fn->addFnAttr(llvm::Attribute::AddressSafety); return Fn; diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp index 85adf35961..cdbd6e7bb7 100644 --- a/lib/CodeGen/CGExpr.cpp +++ b/lib/CodeGen/CGExpr.cpp @@ -487,13 +487,13 @@ void CodeGenFunction::EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc, llvm::Value *Cond = 0; - if (getLangOpts().SanitizeNull) { + if (SanOpts->Null) { // The glvalue must not be an empty glvalue. Cond = Builder.CreateICmpNE( Address, llvm::Constant::getNullValue(Address->getType())); } - if (getLangOpts().SanitizeObjectSize && !Ty->isIncompleteType()) { + if (SanOpts->ObjectSize && !Ty->isIncompleteType()) { uint64_t Size = getContext().getTypeSizeInChars(Ty).getQuantity(); // The glvalue must refer to a large enough storage region. @@ -510,7 +510,7 @@ void CodeGenFunction::EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc, uint64_t AlignVal = 0; - if (getLangOpts().SanitizeAlignment) { + if (SanOpts->Alignment) { AlignVal = Alignment.getQuantity(); if (!Ty->isIncompleteType() && !AlignVal) AlignVal = getContext().getTypeAlignInChars(Ty).getQuantity(); @@ -545,7 +545,7 @@ void CodeGenFunction::EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc, // -- the [pointer or glvalue] is used to access a non-static data member // or call a non-static member function CXXRecordDecl *RD = Ty->getAsCXXRecordDecl(); - if (getLangOpts().SanitizeVptr && + if (SanOpts->Vptr && (TCK == TCK_MemberAccess || TCK == TCK_MemberCall) && RD && RD->hasDefinition() && RD->isDynamicClass()) { // Compute a hash of the mangled name of the type. @@ -1028,8 +1028,8 @@ llvm::Value *CodeGenFunction::EmitLoadOfScalar(llvm::Value *Addr, bool Volatile, if (Ty->isAtomicType()) Load->setAtomic(llvm::SequentiallyConsistent); - if ((getLangOpts().SanitizeBool && hasBooleanRepresentation(Ty)) || - (getLangOpts().SanitizeEnum && Ty->getAs<EnumType>())) { + if ((SanOpts->Bool && hasBooleanRepresentation(Ty)) || + (SanOpts->Enum && Ty->getAs<EnumType>())) { llvm::APInt Min, End; if (getRangeForType(*this, Ty, Min, End, true)) { --End; @@ -1974,6 +1974,7 @@ void CodeGenFunction::EmitCheck(llvm::Value *Checked, StringRef CheckName, ArrayRef<llvm::Constant *> StaticArgs, ArrayRef<llvm::Value *> DynamicArgs, CheckRecoverableKind RecoverKind) { + assert(SanOpts != &SanitizerOptions::Disabled); llvm::BasicBlock *Cont = createBasicBlock("cont"); llvm::BasicBlock *Handler = createBasicBlock("handler." + CheckName); diff --git a/lib/CodeGen/CGExprScalar.cpp b/lib/CodeGen/CGExprScalar.cpp index ebabf76448..5715913b6a 100644 --- a/lib/CodeGen/CGExprScalar.cpp +++ b/lib/CodeGen/CGExprScalar.cpp @@ -406,7 +406,7 @@ public: case LangOptions::SOB_Defined: return Builder.CreateMul(Ops.LHS, Ops.RHS, "mul"); case LangOptions::SOB_Undefined: - if (!CGF.getLangOpts().SanitizeSignedIntegerOverflow) + if (!CGF.SanOpts->SignedIntegerOverflow) return Builder.CreateNSWMul(Ops.LHS, Ops.RHS, "mul"); // Fall through. case LangOptions::SOB_Trapping: @@ -414,8 +414,7 @@ public: } } - if (Ops.Ty->isUnsignedIntegerType() && - CGF.getLangOpts().SanitizeUnsignedIntegerOverflow) + if (Ops.Ty->isUnsignedIntegerType() && CGF.SanOpts->UnsignedIntegerOverflow) return EmitOverflowCheckedBinOp(Ops); if (Ops.LHS->getType()->isFPOrFPVectorTy()) @@ -730,9 +729,10 @@ Value *ScalarExprEmitter::EmitScalarConversion(Value *Src, QualType SrcType, // An overflowing conversion has undefined behavior if either the source type // or the destination type is a floating-point type. - if (CGF.getLangOpts().SanitizeFloatCastOverflow && + if (CGF.SanOpts->FloatCastOverflow && (OrigSrcType->isFloatingType() || DstType->isFloatingType())) - EmitFloatConversionCheck(OrigSrc, OrigSrcType, Src, SrcType, DstType, DstTy); + EmitFloatConversionCheck(OrigSrc, OrigSrcType, Src, SrcType, DstType, + DstTy); // Cast to half via float if (DstType->isHalfType()) @@ -1406,7 +1406,7 @@ EmitAddConsiderOverflowBehavior(const UnaryOperator *E, case LangOptions::SOB_Defined: return Builder.CreateAdd(InVal, NextVal, IsInc ? "inc" : "dec"); case LangOptions::SOB_Undefined: - if (!CGF.getLangOpts().SanitizeSignedIntegerOverflow) + if (!CGF.SanOpts->SignedIntegerOverflow) return Builder.CreateNSWAdd(InVal, NextVal, IsInc ? "inc" : "dec"); // Fall through. case LangOptions::SOB_Trapping: @@ -1466,9 +1466,8 @@ ScalarExprEmitter::EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV, type->isSignedIntegerOrEnumerationType()) { value = EmitAddConsiderOverflowBehavior(E, value, amt, isInc); } else if (value->getType()->getPrimitiveSizeInBits() >= - CGF.IntTy->getBitWidth() && - type->isUnsignedIntegerType() && - CGF.getLangOpts().SanitizeUnsignedIntegerOverflow) { + CGF.IntTy->getBitWidth() && type->isUnsignedIntegerType() && + CGF.SanOpts->UnsignedIntegerOverflow) { BinOpInfo BinOp; BinOp.LHS = value; BinOp.RHS = llvm::ConstantInt::get(value->getType(), 1, false); @@ -1927,10 +1926,10 @@ void ScalarExprEmitter::EmitUndefinedBehaviorIntegerDivAndRemCheck( const BinOpInfo &Ops, llvm::Value *Zero, bool isDiv) { llvm::Value *Cond = 0; - if (CGF.getLangOpts().SanitizeIntegerDivideByZero) + if (CGF.SanOpts->IntegerDivideByZero) Cond = Builder.CreateICmpNE(Ops.RHS, Zero); - if (CGF.getLangOpts().SanitizeSignedIntegerOverflow && + if (CGF.SanOpts->SignedIntegerOverflow && Ops.Ty->hasSignedIntegerRepresentation()) { llvm::IntegerType *Ty = cast<llvm::IntegerType>(Zero->getType()); @@ -1949,12 +1948,12 @@ void ScalarExprEmitter::EmitUndefinedBehaviorIntegerDivAndRemCheck( } Value *ScalarExprEmitter::EmitDiv(const BinOpInfo &Ops) { - if ((CGF.getLangOpts().SanitizeIntegerDivideByZero || - CGF.getLangOpts().SanitizeSignedIntegerOverflow) && + if ((CGF.SanOpts->IntegerDivideByZero || + CGF.SanOpts->SignedIntegerOverflow) && Ops.Ty->isIntegerType()) { llvm::Value *Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty)); EmitUndefinedBehaviorIntegerDivAndRemCheck(Ops, Zero, true); - } else if (CGF.getLangOpts().SanitizeFloatDivideByZero && + } else if (CGF.SanOpts->FloatDivideByZero && Ops.Ty->isRealFloatingType()) { llvm::Value *Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty)); EmitBinOpCheck(Builder.CreateFCmpUNE(Ops.RHS, Zero), Ops); @@ -1980,7 +1979,7 @@ Value *ScalarExprEmitter::EmitDiv(const BinOpInfo &Ops) { Value *ScalarExprEmitter::EmitRem(const BinOpInfo &Ops) { // Rem in C can't be a floating point type: C99 6.5.5p2. - if (CGF.getLangOpts().SanitizeIntegerDivideByZero) { + if (CGF.SanOpts->IntegerDivideByZero) { llvm::Value *Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty)); if (Ops.Ty->isIntegerType()) @@ -2038,7 +2037,7 @@ Value *ScalarExprEmitter::EmitOverflowCheckedBinOp(const BinOpInfo &Ops) { if (handlerName->empty()) { // If the signed-integer-overflow sanitizer is enabled, emit a call to its // runtime. Otherwise, this is a -ftrapv check, so just emit a trap. - if (!isSigned || CGF.getLangOpts().SanitizeSignedIntegerOverflow) + if (!isSigned || CGF.SanOpts->SignedIntegerOverflow) EmitBinOpCheck(Builder.CreateNot(overflow), Ops); else CGF.EmitTrapvCheck(Builder.CreateNot(overflow)); @@ -2256,7 +2255,7 @@ Value *ScalarExprEmitter::EmitAdd(const BinOpInfo &op) { case LangOptions::SOB_Defined: return Builder.CreateAdd(op.LHS, op.RHS, "add"); case LangOptions::SOB_Undefined: - if (!CGF.getLangOpts().SanitizeSignedIntegerOverflow) + if (!CGF.SanOpts->SignedIntegerOverflow) return Builder.CreateNSWAdd(op.LHS, op.RHS, "add"); // Fall through. case LangOptions::SOB_Trapping: @@ -2264,8 +2263,7 @@ Value *ScalarExprEmitter::EmitAdd(const BinOpInfo &op) { } } - if (op.Ty->isUnsignedIntegerType() && - CGF.getLangOpts().SanitizeUnsignedIntegerOverflow) + if (op.Ty->isUnsignedIntegerType() && CGF.SanOpts->UnsignedIntegerOverflow) return EmitOverflowCheckedBinOp(op); if (op.LHS->getType()->isFPOrFPVectorTy()) { @@ -2287,7 +2285,7 @@ Value *ScalarExprEmitter::EmitSub(const BinOpInfo &op) { case LangOptions::SOB_Defined: return Builder.CreateSub(op.LHS, op.RHS, "sub"); case LangOptions::SOB_Undefined: - if (!CGF.getLangOpts().SanitizeSignedIntegerOverflow) + if (!CGF.SanOpts->SignedIntegerOverflow) return Builder.CreateNSWSub(op.LHS, op.RHS, "sub"); // Fall through. case LangOptions::SOB_Trapping: @@ -2295,8 +2293,7 @@ Value *ScalarExprEmitter::EmitSub(const BinOpInfo &op) { } } - if (op.Ty->isUnsignedIntegerType() && - CGF.getLangOpts().SanitizeUnsignedIntegerOverflow) + if (op.Ty->isUnsignedIntegerType() && CGF.SanOpts->UnsignedIntegerOverflow) return EmitOverflowCheckedBinOp(op); if (op.LHS->getType()->isFPOrFPVectorTy()) { @@ -2383,8 +2380,8 @@ Value *ScalarExprEmitter::EmitShl(const BinOpInfo &Ops) { if (Ops.LHS->getType() != RHS->getType()) RHS = Builder.CreateIntCast(RHS, Ops.LHS->getType(), false, "sh_prom"); - if (CGF.getLangOpts().SanitizeShift && !CGF.getLangOpts().OpenCL - && isa<llvm::IntegerType>(Ops.LHS->getType())) { + if (CGF.SanOpts->Shift && !CGF.getLangOpts().OpenCL && + isa<llvm::IntegerType>(Ops.LHS->getType())) { llvm::Value *WidthMinusOne = GetWidthMinusOneValue(Ops.LHS, RHS); // FIXME: Emit the branching explicitly rather than emitting the check // twice. @@ -2424,8 +2421,8 @@ Value *ScalarExprEmitter::EmitShr(const BinOpInfo &Ops) { if (Ops.LHS->getType() != RHS->getType()) RHS = Builder.CreateIntCast(RHS, Ops.LHS->getType(), false, "sh_prom"); - if (CGF.getLangOpts().SanitizeShift && !CGF.getLangOpts().OpenCL - && isa<llvm::IntegerType>(Ops.LHS->getType())) + if (CGF.SanOpts->Shift && !CGF.getLangOpts().OpenCL && + isa<llvm::IntegerType>(Ops.LHS->getType())) EmitBinOpCheck(Builder.CreateICmpULE(RHS, GetWidthMinusOneValue(Ops.LHS, RHS)), Ops); // OpenCL 6.3j: shift values are effectively % word size of LHS. diff --git a/lib/CodeGen/CodeGenFunction.cpp b/lib/CodeGen/CodeGenFunction.cpp index 8ba1bf4b6f..1fdcc6f9ec 100644 --- a/lib/CodeGen/CodeGenFunction.cpp +++ b/lib/CodeGen/CodeGenFunction.cpp @@ -33,10 +33,11 @@ CodeGenFunction::CodeGenFunction(CodeGenModule &cgm, bool suppressNewContext) : CodeGenTypeCache(cgm), CGM(cgm), Target(CGM.getContext().getTargetInfo()), Builder(cgm.getModule().getContext()), - SanitizePerformTypeCheck(CGM.getLangOpts().SanitizeNull | - CGM.getLangOpts().SanitizeAlignment | - CGM.getLangOpts().SanitizeObjectSize | - CGM.getLangOpts().SanitizeVptr), + SanitizePerformTypeCheck(CGM.getSanOpts().Null | + CGM.getSanOpts().Alignment | + CGM.getSanOpts().ObjectSize | + CGM.getSanOpts().Vptr), + SanOpts(&CGM.getSanOpts()), AutoreleaseResult(false), BlockInfo(0), BlockPointer(0), LambdaThisCaptureField(0), NormalCleanupDest(0), NextCleanupDestIndex(1), FirstBlockInfo(0), EHResumeBlock(0), ExceptionSlot(0), EHSelectorSlot(0), @@ -347,6 +348,11 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy, CurFnInfo = &FnInfo; assert(CurFn->isDeclaration() && "Function already has body?"); + if (CGM.getSanitizerBlacklist().isIn(*Fn)) { + SanOpts = &SanitizerOptions::Disabled; + SanitizePerformTypeCheck = false; + } + // Pass inline keyword to optimizer if it appears explicitly on any // declaration. if (!CGM.getCodeGenOpts().NoInline) @@ -558,7 +564,7 @@ void CodeGenFunction::GenerateCode(GlobalDecl GD, llvm::Function *Fn, // function call is used by the caller, the behavior is undefined. if (getLangOpts().CPlusPlus && !FD->hasImplicitReturnZero() && !FD->getResultType()->isVoidType() && Builder.GetInsertBlock()) { - if (getLangOpts().SanitizeReturn) + if (SanOpts->Return) EmitCheck(Builder.getFalse(), "missing_return", EmitCheckSourceLocation(FD->getLocation()), ArrayRef<llvm::Value *>(), CRK_Unrecoverable); @@ -1143,7 +1149,7 @@ void CodeGenFunction::EmitVariablyModifiedType(QualType type) { // If the size is an expression that is not an integer constant // expression [...] each time it is evaluated it shall have a value // greater than zero. - if (getLangOpts().SanitizeVLABound && + if (SanOpts->VLABound && size->getType()->isSignedIntegerType()) { llvm::Value *Zero = llvm::Constant::getNullValue(Size->getType()); llvm::Constant *StaticArgs[] = { diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h index 61122666a1..afe99381ae 100644 --- a/lib/CodeGen/CodeGenFunction.h +++ b/lib/CodeGen/CodeGenFunction.h @@ -598,6 +598,9 @@ public: /// calls to EmitTypeCheck can be skipped. bool SanitizePerformTypeCheck; + /// \brief Sanitizer options to use for this function. + const SanitizerOptions *SanOpts; + /// In ARC, whether we should autorelease the return value. bool AutoreleaseResult; @@ -800,7 +803,7 @@ public: protected: CodeGenFunction& CGF; - + public: /// \brief Enter a new cleanup scope. explicit RunCleanupsScope(CodeGenFunction &CGF) diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp index 04a08a92d8..9faba75433 100644 --- a/lib/CodeGen/CodeGenModule.cpp +++ b/lib/CodeGen/CodeGenModule.cpp @@ -77,8 +77,11 @@ CodeGenModule::CodeGenModule(ASTContext &C, const CodeGenOptions &CGO, VMContext(M.getContext()), NSConcreteGlobalBlock(0), NSConcreteStackBlock(0), BlockObjectAssign(0), BlockObjectDispose(0), - BlockDescriptorType(0), GenericBlockLiteralType(0) { - + BlockDescriptorType(0), GenericBlockLiteralType(0), + SanitizerBlacklist(CGO.SanitizerBlacklistFile), + SanOpts(SanitizerBlacklist.isIn(M) ? + SanitizerOptions::Disabled : LangOpts.Sanitize) { + // Initialize the type cache. llvm::LLVMContext &LLVMContext = M.getContext(); VoidTy = llvm::Type::getVoidTy(LLVMContext); @@ -104,7 +107,7 @@ CodeGenModule::CodeGenModule(ASTContext &C, const CodeGenOptions &CGO, createCUDARuntime(); // Enable TBAA unless it's suppressed. ThreadSanitizer needs TBAA even at O0. - if (LangOpts.SanitizeThread || + if (SanOpts.Thread || (!CodeGenOpts.RelaxedAliasing && CodeGenOpts.OptimizationLevel > 0)) TBAA = new CodeGenTBAA(Context, VMContext, CodeGenOpts, getLangOpts(), ABI.getMangleContext()); @@ -603,8 +606,8 @@ void CodeGenModule::SetLLVMFunctionAttributesForDefinition(const Decl *D, F->addFnAttr(llvm::Attribute::StackProtect); else if (LangOpts.getStackProtector() == LangOptions::SSPReq) F->addFnAttr(llvm::Attribute::StackProtectReq); - - if (LangOpts.SanitizeAddress) { + + if (SanOpts.Address) { // When AddressSanitizer is enabled, set AddressSafety attribute // unless __attribute__((no_address_safety_analysis)) is used. if (!D->hasAttr<NoAddressSafetyAnalysisAttr>()) @@ -1851,7 +1854,7 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D) { // If we are compiling with ASan, add metadata indicating dynamically // initialized globals. - if (LangOpts.SanitizeAddress && NeedsGlobalCtor) { + if (SanOpts.Address && NeedsGlobalCtor) { llvm::Module &M = getModule(); llvm::NamedMDNode *DynamicInitializers = diff --git a/lib/CodeGen/CodeGenModule.h b/lib/CodeGen/CodeGenModule.h index 00a98a6424..0f011205a7 100644 --- a/lib/CodeGen/CodeGenModule.h +++ b/lib/CodeGen/CodeGenModule.h @@ -30,6 +30,7 @@ #include "llvm/ADT/StringMap.h" #include "llvm/IR/Module.h" #include "llvm/Support/ValueHandle.h" +#include "llvm/Transforms/Utils/BlackList.h" namespace llvm { class Module; @@ -209,7 +210,7 @@ struct ARCEntrypoints { /// a call will be immediately retain. llvm::InlineAsm *retainAutoreleasedReturnValueMarker; }; - + /// CodeGenModule - This class organizes the cross-function state that is used /// while generating LLVM code. class CodeGenModule : public CodeGenTypeCache { @@ -364,9 +365,13 @@ class CodeGenModule : public CodeGenTypeCache { struct { int GlobalUniqueCount; } Block; - + GlobalDecl initializedGlobalDecl; + llvm::BlackList SanitizerBlacklist; + + const SanitizerOptions &SanOpts; + /// @} public: CodeGenModule(ASTContext &C, const CodeGenOptions &CodeGenOpts, @@ -889,6 +894,12 @@ public: /// annotations are emitted during finalization of the LLVM code. void AddGlobalAnnotations(const ValueDecl *D, llvm::GlobalValue *GV); + const llvm::BlackList &getSanitizerBlacklist() const { + return SanitizerBlacklist; + } + + const SanitizerOptions &getSanOpts() const { return SanOpts; } + private: llvm::GlobalValue *GetGlobalValue(StringRef Ref); diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index e810a22dce..2c02c423c1 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/lib/Frontend/CompilerInvocation.cpp @@ -1300,7 +1300,7 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, .Default(Unknown)) { #define SANITIZER(NAME, ID) \ case ID: \ - Opts.Sanitize##ID = true; \ + Opts.Sanitize.ID = true; \ break; #include "clang/Basic/Sanitizers.def" diff --git a/lib/Lex/PPMacroExpansion.cpp b/lib/Lex/PPMacroExpansion.cpp index e8a1f8dd88..7901705fec 100644 --- a/lib/Lex/PPMacroExpansion.cpp +++ b/lib/Lex/PPMacroExpansion.cpp @@ -785,7 +785,7 @@ static bool HasFeature(const Preprocessor &PP, const IdentifierInfo *II) { Feature = Feature.substr(2, Feature.size() - 4); return llvm::StringSwitch<bool>(Feature) - .Case("address_sanitizer", LangOpts.SanitizeAddress) + .Case("address_sanitizer", LangOpts.Sanitize.Address) .Case("attribute_analyzer_noreturn", true) .Case("attribute_availability", true) .Case("attribute_availability_with_message", true) @@ -807,8 +807,8 @@ static bool HasFeature(const Preprocessor &PP, const IdentifierInfo *II) { .Case("cxx_exceptions", LangOpts.Exceptions) .Case("cxx_rtti", LangOpts.RTTI) .Case("enumerator_attributes", true) - .Case("memory_sanitizer", LangOpts.SanitizeMemory) - .Case("thread_sanitizer", LangOpts.SanitizeThread) + .Case("memory_sanitizer", LangOpts.Sanitize.Memory) + .Case("thread_sanitizer", LangOpts.Sanitize.Thread) // Objective-C features .Case("objc_arr", LangOpts.ObjCAutoRefCount) // FIXME: REMOVE? .Case("objc_arc", LangOpts.ObjCAutoRefCount) diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp index 81d3cea7ba..1bafc2a4c5 100644 --- a/lib/Serialization/ASTReader.cpp +++ b/lib/Serialization/ASTReader.cpp @@ -3638,6 +3638,8 @@ bool ASTReader::ParseLanguageOptions(const RecordData &Record, #define ENUM_LANGOPT(Name, Type, Bits, Default, Description) \ LangOpts.set##Name(static_cast<LangOptions::Type>(Record[Idx++])); #include "clang/Basic/LangOptions.def" +#define SANITIZER(NAME, ID) LangOpts.Sanitize.ID = Record[Idx++]; +#include "clang/Basic/Sanitizers.def" ObjCRuntime::Kind runtimeKind = (ObjCRuntime::Kind) Record[Idx++]; VersionTuple runtimeVersion = ReadVersionTuple(Record, Idx); diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp index 36e1bb3a69..37577ce071 100644 --- a/lib/Serialization/ASTWriter.cpp +++ b/lib/Serialization/ASTWriter.cpp @@ -1048,6 +1048,8 @@ void ASTWriter::WriteControlBlock(Preprocessor &PP, ASTContext &Context, #define ENUM_LANGOPT(Name, Type, Bits, Default, Description) \ Record.push_back(static_cast<unsigned>(LangOpts.get##Name())); #include "clang/Basic/LangOptions.def" +#define SANITIZER(NAME, ID) Record.push_back(LangOpts.Sanitize.ID); +#include "clang/Basic/Sanitizers.def" Record.push_back((unsigned) LangOpts.ObjCRuntime.getKind()); AddVersionTuple(LangOpts.ObjCRuntime.getVersion(), Record); |