diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2012-11-05 22:21:05 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2012-11-05 22:21:05 +0000 |
commit | d6396a681c9acbe56bc41bbc2bed2db45755bcd7 (patch) | |
tree | 71cbf2d2406448392b82ddc93db485a9d10d68de /lib/CodeGen | |
parent | c4dabadb51475e76b606024f144e7cf93b0bad00 (diff) |
Use the individual -fsanitize=<...> arguments to control which of the UBSan
checks to enable. Remove frontend support for -fcatch-undefined-behavior,
-faddress-sanitizer and -fthread-sanitizer now that they don't do anything.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@167413 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen')
-rw-r--r-- | lib/CodeGen/CGBuiltin.cpp | 2 | ||||
-rw-r--r-- | lib/CodeGen/CGExpr.cpp | 50 | ||||
-rw-r--r-- | lib/CodeGen/CGExprScalar.cpp | 26 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenFunction.cpp | 11 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenFunction.h | 5 |
5 files changed, 52 insertions, 42 deletions
diff --git a/lib/CodeGen/CGBuiltin.cpp b/lib/CodeGen/CGBuiltin.cpp index b0ea2fab20..e8c05d3a46 100644 --- a/lib/CodeGen/CGBuiltin.cpp +++ b/lib/CodeGen/CGBuiltin.cpp @@ -406,7 +406,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD, return RValue::get(Builder.CreateCall(F)); } case Builtin::BI__builtin_unreachable: { - if (CatchUndefined) + if (getLangOpts().SanitizeUnreachable) EmitCheck(Builder.getFalse(), "builtin_unreachable", EmitCheckSourceLocation(E->getExprLoc()), llvm::ArrayRef<llvm::Value *>()); diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp index 625558542a..d1a2889f9a 100644 --- a/lib/CodeGen/CGExpr.cpp +++ b/lib/CodeGen/CGExpr.cpp @@ -389,7 +389,7 @@ CodeGenFunction::EmitReferenceBindingToExpr(const Expr *E, ReferenceTemporaryDtor, ObjCARCReferenceLifetimeType, InitializedDecl); - if (CatchUndefined && !E->getType()->isFunctionType()) { + if (SanitizePerformTypeCheck && !E->getType()->isFunctionType()) { // C++11 [dcl.ref]p5 (as amended by core issue 453): // If a glvalue to which a reference is directly bound designates neither // an existing object or function of an appropriate type nor a region of @@ -476,7 +476,7 @@ static llvm::Value *emitHash16Bytes(CGBuilderTy &Builder, llvm::Value *Low, void CodeGenFunction::EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc, llvm::Value *Address, QualType Ty, CharUnits Alignment) { - if (!CatchUndefined) + if (!SanitizePerformTypeCheck) return; // Don't check pointers outside the default address space. The null check @@ -487,19 +487,17 @@ void CodeGenFunction::EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc, llvm::Value *Cond = 0; - // The glvalue must not be an empty glvalue. - Cond = Builder.CreateICmpNE( - Address, llvm::Constant::getNullValue(Address->getType())); - - uint64_t AlignVal = Alignment.getQuantity(); + if (getLangOpts().SanitizeNull) { + // The glvalue must not be an empty glvalue. + Cond = Builder.CreateICmpNE( + Address, llvm::Constant::getNullValue(Address->getType())); + } - if (!Ty->isIncompleteType()) { + if (getLangOpts().SanitizeObjectSize && !Ty->isIncompleteType()) { uint64_t Size = getContext().getTypeSizeInChars(Ty).getQuantity(); - if (!AlignVal) - AlignVal = getContext().getTypeAlignInChars(Ty).getQuantity(); // The glvalue must refer to a large enough storage region. - // FIXME: If -faddress-sanitizer is enabled, insert dynamic instrumentation + // FIXME: If Address Sanitizer is enabled, insert dynamic instrumentation // to check this. llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::objectsize, IntPtrTy); llvm::Value *Min = Builder.getFalse(); @@ -510,13 +508,22 @@ void CodeGenFunction::EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc, Cond = Cond ? Builder.CreateAnd(Cond, LargeEnough) : LargeEnough; } - if (AlignVal) { + uint64_t AlignVal = 0; + + if (getLangOpts().SanitizeAlignment) { + AlignVal = Alignment.getQuantity(); + if (!Ty->isIncompleteType() && !AlignVal) + AlignVal = getContext().getTypeAlignInChars(Ty).getQuantity(); + // The glvalue must be suitably aligned. - llvm::Value *Align = - Builder.CreateAnd(Builder.CreatePtrToInt(Address, IntPtrTy), - llvm::ConstantInt::get(IntPtrTy, AlignVal - 1)); - Cond = Builder.CreateAnd(Cond, - Builder.CreateICmpEQ(Align, llvm::ConstantInt::get(IntPtrTy, 0))); + if (AlignVal) { + llvm::Value *Align = + Builder.CreateAnd(Builder.CreatePtrToInt(Address, IntPtrTy), + llvm::ConstantInt::get(IntPtrTy, AlignVal - 1)); + llvm::Value *Aligned = + Builder.CreateICmpEQ(Align, llvm::ConstantInt::get(IntPtrTy, 0)); + Cond = Cond ? Builder.CreateAnd(Cond, Aligned) : Aligned; + } } if (Cond) { @@ -529,14 +536,11 @@ void CodeGenFunction::EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc, EmitCheck(Cond, "type_mismatch", StaticData, Address); } + // If possible, check that the vptr indicates that there is a subobject of + // type Ty at offset zero within this object. CXXRecordDecl *RD = Ty->getAsCXXRecordDecl(); - if (TCK != TCK_ConstructorCall && + if (getLangOpts().SanitizeVptr && TCK != TCK_ConstructorCall && RD && RD->hasDefinition() && RD->isDynamicClass()) { - // Check that the vptr indicates that there is a subobject of type Ty at - // offset zero within this object. - // FIXME: Produce a diagnostic if the user tries to combine this check with - // -fno-rtti. - // Compute a hash of the mangled name of the type. // // FIXME: This is not guaranteed to be deterministic! Move to a diff --git a/lib/CodeGen/CGExprScalar.cpp b/lib/CodeGen/CGExprScalar.cpp index b6ce22becf..c21cbf6773 100644 --- a/lib/CodeGen/CGExprScalar.cpp +++ b/lib/CodeGen/CGExprScalar.cpp @@ -406,14 +406,14 @@ public: case LangOptions::SOB_Defined: return Builder.CreateMul(Ops.LHS, Ops.RHS, "mul"); case LangOptions::SOB_Undefined: - if (!CGF.CatchUndefined) + if (!CGF.getLangOpts().SanitizeSignedIntegerOverflow) return Builder.CreateNSWMul(Ops.LHS, Ops.RHS, "mul"); // Fall through. case LangOptions::SOB_Trapping: return EmitOverflowCheckedBinOp(Ops); } } - + if (Ops.LHS->getType()->isFPOrFPVectorTy()) return Builder.CreateFMul(Ops.LHS, Ops.RHS, "mul"); return Builder.CreateMul(Ops.LHS, Ops.RHS, "mul"); @@ -731,7 +731,7 @@ 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.CatchUndefined && + if (CGF.getLangOpts().SanitizeFloatCastOverflow && (OrigSrcType->isFloatingType() || DstType->isFloatingType())) EmitFloatConversionCheck(OrigSrc, OrigSrcType, Src, SrcType, DstType, DstTy); @@ -1417,7 +1417,7 @@ EmitAddConsiderOverflowBehavior(const UnaryOperator *E, case LangOptions::SOB_Defined: return Builder.CreateAdd(InVal, NextVal, IsInc ? "inc" : "dec"); case LangOptions::SOB_Undefined: - if (!CGF.CatchUndefined) + if (!CGF.getLangOpts().SanitizeSignedIntegerOverflow) return Builder.CreateNSWAdd(InVal, NextVal, IsInc ? "inc" : "dec"); // Fall through. case LangOptions::SOB_Trapping: @@ -1942,7 +1942,7 @@ void ScalarExprEmitter::EmitUndefinedBehaviorIntegerDivAndRemCheck( } Value *ScalarExprEmitter::EmitDiv(const BinOpInfo &Ops) { - if (CGF.CatchUndefined) { + if (CGF.getLangOpts().SanitizeDivideByZero) { llvm::Value *Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty)); if (Ops.Ty->isIntegerType()) @@ -1970,7 +1970,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.CatchUndefined) { + if (CGF.getLangOpts().SanitizeDivideByZero) { llvm::Value *Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty)); if (Ops.Ty->isIntegerType()) @@ -2021,9 +2021,9 @@ Value *ScalarExprEmitter::EmitOverflowCheckedBinOp(const BinOpInfo &Ops) { const std::string *handlerName = &CGF.getLangOpts().OverflowHandler; if (handlerName->empty()) { - // If -fcatch-undefined-behavior is enabled, emit a call to its + // 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 (CGF.CatchUndefined) + if (CGF.getLangOpts().SanitizeSignedIntegerOverflow) EmitBinOpCheck(Builder.CreateNot(overflow), Ops); else CGF.EmitTrapvCheck(Builder.CreateNot(overflow)); @@ -2241,7 +2241,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.CatchUndefined) + if (!CGF.getLangOpts().SanitizeSignedIntegerOverflow) return Builder.CreateNSWAdd(op.LHS, op.RHS, "add"); // Fall through. case LangOptions::SOB_Trapping: @@ -2268,7 +2268,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.CatchUndefined) + if (!CGF.getLangOpts().SanitizeSignedIntegerOverflow) return Builder.CreateNSWSub(op.LHS, op.RHS, "sub"); // Fall through. case LangOptions::SOB_Trapping: @@ -2351,7 +2351,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.CatchUndefined && isa<llvm::IntegerType>(Ops.LHS->getType())) { + if (CGF.getLangOpts().SanitizeShift && + isa<llvm::IntegerType>(Ops.LHS->getType())) { unsigned Width = cast<llvm::IntegerType>(Ops.LHS->getType())->getBitWidth(); llvm::Value *WidthMinusOne = llvm::ConstantInt::get(RHS->getType(), Width - 1); @@ -2390,7 +2391,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.CatchUndefined && isa<llvm::IntegerType>(Ops.LHS->getType())) { + if (CGF.getLangOpts().SanitizeShift && + isa<llvm::IntegerType>(Ops.LHS->getType())) { unsigned Width = cast<llvm::IntegerType>(Ops.LHS->getType())->getBitWidth(); llvm::Value *WidthVal = llvm::ConstantInt::get(RHS->getType(), Width); EmitBinOpCheck(Builder.CreateICmpULT(RHS, WidthVal), Ops); diff --git a/lib/CodeGen/CodeGenFunction.cpp b/lib/CodeGen/CodeGenFunction.cpp index 140f1cb30a..18f1623d24 100644 --- a/lib/CodeGen/CodeGenFunction.cpp +++ b/lib/CodeGen/CodeGenFunction.cpp @@ -32,6 +32,10 @@ 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), AutoreleaseResult(false), BlockInfo(0), BlockPointer(0), LambdaThisCaptureField(0), NormalCleanupDest(0), NextCleanupDestIndex(1), FirstBlockInfo(0), EHResumeBlock(0), ExceptionSlot(0), EHSelectorSlot(0), @@ -40,8 +44,6 @@ CodeGenFunction::CodeGenFunction(CodeGenModule &cgm, bool suppressNewContext) CXXABIThisDecl(0), CXXABIThisValue(0), CXXThisValue(0), CXXVTTDecl(0), CXXVTTValue(0), OutermostConditional(0), TerminateLandingPad(0), TerminateHandler(0), TrapBB(0) { - - CatchUndefined = getLangOpts().CatchUndefined; if (!suppressNewContext) CGM.getCXXABI().getMangleContext().startNewFunction(); } @@ -543,7 +545,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 (CatchUndefined) + if (getLangOpts().SanitizeReturn) EmitCheck(Builder.getFalse(), "missing_return", EmitCheckSourceLocation(FD->getLocation()), llvm::ArrayRef<llvm::Value*>()); @@ -1128,7 +1130,8 @@ 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 (CatchUndefined && size->getType()->isSignedIntegerType()) { + if (getLangOpts().SanitizeVLABound && + size->getType()->isSignedIntegerType()) { llvm::Value *Zero = llvm::Constant::getNullValue(Size->getType()); llvm::Constant *StaticArgs[] = { EmitCheckSourceLocation(size->getLocStart()), diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h index 1e9fd006d0..fadc391328 100644 --- a/lib/CodeGen/CodeGenFunction.h +++ b/lib/CodeGen/CodeGenFunction.h @@ -594,8 +594,9 @@ public: /// potentially higher performance penalties. unsigned char BoundsChecking; - /// CatchUndefined - Emit run-time checks to catch undefined behaviors. - bool CatchUndefined; + /// \brief Whether any type-checking sanitizers are enabled. If \c false, + /// calls to EmitTypeCheck can be skipped. + bool SanitizePerformTypeCheck; /// In ARC, whether we should autorelease the return value. bool AutoreleaseResult; |