Author: samsonov Date: Thu Jul 17 13:46:27 2014 New Revision: 213291 URL: http://llvm.org/viewvc/llvm-project?rev=213291&view=rev Log: [UBSan] Add !nosanitize metadata to the code generated by UBSan.
This is used to mark the instructions emitted by Clang to implement variety of UBSan checks. Generally, we don't want to instrument these instructions with another sanitizers (like ASan). Reviewed in http://reviews.llvm.org/D4544 Modified: cfe/trunk/lib/CodeGen/CGBuiltin.cpp cfe/trunk/lib/CodeGen/CGExpr.cpp cfe/trunk/lib/CodeGen/CGExprScalar.cpp cfe/trunk/lib/CodeGen/CodeGenFunction.cpp cfe/trunk/lib/CodeGen/CodeGenFunction.h cfe/trunk/test/CodeGen/catch-undef-behavior.c Modified: cfe/trunk/lib/CodeGen/CGBuiltin.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGBuiltin.cpp?rev=213291&r1=213290&r2=213291&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CGBuiltin.cpp (original) +++ cfe/trunk/lib/CodeGen/CGBuiltin.cpp Thu Jul 17 13:46:27 2014 @@ -447,11 +447,12 @@ RValue CodeGenFunction::EmitBuiltinExpr( return RValue::get(Builder.CreateCall(F)); } case Builtin::BI__builtin_unreachable: { - if (SanOpts->Unreachable) + if (SanOpts->Unreachable) { + SanitizerScope SanScope(this); EmitCheck(Builder.getFalse(), "builtin_unreachable", EmitCheckSourceLocation(E->getExprLoc()), ArrayRef<llvm::Value *>(), CRK_Unrecoverable); - else + } else Builder.CreateUnreachable(); // We do need to preserve an insertion point. Modified: cfe/trunk/lib/CodeGen/CGExpr.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=213291&r1=213290&r2=213291&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CGExpr.cpp (original) +++ cfe/trunk/lib/CodeGen/CGExpr.cpp Thu Jul 17 13:46:27 2014 @@ -458,6 +458,8 @@ void CodeGenFunction::EmitTypeCheck(Type if (Address->getType()->getPointerAddressSpace()) return; + SanitizerScope SanScope(this); + llvm::Value *Cond = nullptr; llvm::BasicBlock *Done = nullptr; @@ -654,6 +656,7 @@ void CodeGenFunction::EmitBoundsCheck(co bool Accessed) { assert(SanOpts->ArrayBounds && "should not be called unless adding bounds checks"); + SanitizerScope SanScope(this); QualType IndexedType; llvm::Value *Bound = getArrayIndexingBound(*this, Base, IndexedType); @@ -1129,6 +1132,7 @@ llvm::Value *CodeGenFunction::EmitLoadOf if ((SanOpts->Bool && hasBooleanRepresentation(Ty)) || (SanOpts->Enum && Ty->getAs<EnumType>())) { + SanitizerScope SanScope(this); llvm::APInt Min, End; if (getRangeForType(*this, Ty, Min, End, true)) { --End; @@ -2183,6 +2187,7 @@ void CodeGenFunction::EmitCheck(llvm::Va ArrayRef<llvm::Value *> DynamicArgs, CheckRecoverableKind RecoverKind) { assert(SanOpts != &SanitizerOptions::Disabled); + assert(IsSanitizerScope); if (CGM.getCodeGenOpts().SanitizeUndefinedTrapOnError) { assert (RecoverKind != CRK_AlwaysRecoverable && @@ -3231,6 +3236,7 @@ RValue CodeGenFunction::EmitCall(QualTyp (!TargetDecl || !isa<FunctionDecl>(TargetDecl))) { if (llvm::Constant *PrefixSig = CGM.getTargetCodeGenInfo().getUBSanFunctionSignature(CGM)) { + SanitizerScope SanScope(this); llvm::Constant *FTRTTIConst = CGM.GetAddrOfRTTIDescriptor(QualType(FnType, 0), /*ForEH=*/true); llvm::Type *PrefixStructTyElems[] = { Modified: cfe/trunk/lib/CodeGen/CGExprScalar.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprScalar.cpp?rev=213291&r1=213290&r2=213291&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CGExprScalar.cpp (original) +++ cfe/trunk/lib/CodeGen/CGExprScalar.cpp Thu Jul 17 13:46:27 2014 @@ -554,6 +554,7 @@ void ScalarExprEmitter::EmitFloatConvers Value *Src, QualType SrcType, QualType DstType, llvm::Type *DstTy) { + CodeGenFunction::SanitizerScope SanScope(&CGF); using llvm::APFloat; using llvm::APSInt; @@ -840,6 +841,7 @@ Value *ScalarExprEmitter::EmitNullValue( /// might actually be a unary increment which has been lowered to a binary /// operation). The check passes if \p Check, which is an \c i1, is \c true. void ScalarExprEmitter::EmitBinOpCheck(Value *Check, const BinOpInfo &Info) { + assert(CGF.IsSanitizerScope); StringRef CheckName; SmallVector<llvm::Constant *, 4> StaticData; SmallVector<llvm::Value *, 2> DynamicData; @@ -2153,15 +2155,18 @@ void ScalarExprEmitter::EmitUndefinedBeh } Value *ScalarExprEmitter::EmitDiv(const BinOpInfo &Ops) { - 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.SanOpts->FloatDivideByZero && - Ops.Ty->isRealFloatingType()) { - llvm::Value *Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty)); - EmitBinOpCheck(Builder.CreateFCmpUNE(Ops.RHS, Zero), Ops); + { + CodeGenFunction::SanitizerScope SanScope(&CGF); + 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.SanOpts->FloatDivideByZero && + Ops.Ty->isRealFloatingType()) { + llvm::Value *Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty)); + EmitBinOpCheck(Builder.CreateFCmpUNE(Ops.RHS, Zero), Ops); + } } if (Ops.LHS->getType()->isFPOrFPVectorTy()) { @@ -2185,6 +2190,7 @@ Value *ScalarExprEmitter::EmitDiv(const Value *ScalarExprEmitter::EmitRem(const BinOpInfo &Ops) { // Rem in C can't be a floating point type: C99 6.5.5p2. if (CGF.SanOpts->IntegerDivideByZero) { + CodeGenFunction::SanitizerScope SanScope(&CGF); llvm::Value *Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty)); if (Ops.Ty->isIntegerType()) @@ -2242,9 +2248,10 @@ Value *ScalarExprEmitter::EmitOverflowCh 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.SanOpts->SignedIntegerOverflow) + if (!isSigned || CGF.SanOpts->SignedIntegerOverflow) { + CodeGenFunction::SanitizerScope SanScope(&CGF); EmitBinOpCheck(Builder.CreateNot(overflow), Ops); - else + } else CGF.EmitTrapCheck(Builder.CreateNot(overflow)); return result; } @@ -2596,6 +2603,7 @@ Value *ScalarExprEmitter::EmitShl(const if (CGF.SanOpts->Shift && !CGF.getLangOpts().OpenCL && isa<llvm::IntegerType>(Ops.LHS->getType())) { + CodeGenFunction::SanitizerScope SanScope(&CGF); llvm::Value *WidthMinusOne = GetWidthMinusOneValue(Ops.LHS, RHS); llvm::Value *Valid = Builder.CreateICmpULE(RHS, WidthMinusOne); @@ -2647,8 +2655,10 @@ Value *ScalarExprEmitter::EmitShr(const RHS = Builder.CreateIntCast(RHS, Ops.LHS->getType(), false, "sh_prom"); if (CGF.SanOpts->Shift && !CGF.getLangOpts().OpenCL && - isa<llvm::IntegerType>(Ops.LHS->getType())) + isa<llvm::IntegerType>(Ops.LHS->getType())) { + CodeGenFunction::SanitizerScope SanScope(&CGF); EmitBinOpCheck(Builder.CreateICmpULE(RHS, GetWidthMinusOneValue(Ops.LHS, RHS)), Ops); + } // OpenCL 6.3j: shift values are effectively % word size of LHS. if (CGF.getLangOpts().OpenCL) Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.cpp?rev=213291&r1=213290&r2=213291&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CodeGenFunction.cpp (original) +++ cfe/trunk/lib/CodeGen/CodeGenFunction.cpp Thu Jul 17 13:46:27 2014 @@ -36,8 +36,9 @@ using namespace CodeGen; CodeGenFunction::CodeGenFunction(CodeGenModule &cgm, bool suppressNewContext) : CodeGenTypeCache(cgm), CGM(cgm), Target(cgm.getTarget()), Builder(cgm.getModule().getContext(), llvm::ConstantFolder(), - CGBuilderInserterTy(this)), CapturedStmtInfo(nullptr), - SanOpts(&CGM.getLangOpts().Sanitize), AutoreleaseResult(false), BlockInfo(nullptr), + CGBuilderInserterTy(this)), + CapturedStmtInfo(nullptr), SanOpts(&CGM.getLangOpts().Sanitize), + IsSanitizerScope(false), AutoreleaseResult(false), BlockInfo(nullptr), BlockPointer(nullptr), LambdaThisCaptureField(nullptr), NormalCleanupDest(nullptr), NextCleanupDestIndex(1), FirstBlockInfo(nullptr), EHResumeBlock(nullptr), ExceptionSlot(nullptr), @@ -843,11 +844,12 @@ void CodeGenFunction::GenerateCode(Globa // function call is used by the caller, the behavior is undefined. if (getLangOpts().CPlusPlus && !FD->hasImplicitReturnZero() && !FD->getReturnType()->isVoidType() && Builder.GetInsertBlock()) { - if (SanOpts->Return) + if (SanOpts->Return) { + SanitizerScope SanScope(this); EmitCheck(Builder.getFalse(), "missing_return", EmitCheckSourceLocation(FD->getLocation()), ArrayRef<llvm::Value *>(), CRK_Unrecoverable); - else if (CGM.getCodeGenOpts().OptimizationLevel == 0) + } else if (CGM.getCodeGenOpts().OptimizationLevel == 0) Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::trap)); Builder.CreateUnreachable(); Builder.ClearInsertionPoint(); @@ -1499,6 +1501,7 @@ void CodeGenFunction::EmitVariablyModifi // greater than zero. if (SanOpts->VLABound && size->getType()->isSignedIntegerType()) { + SanitizerScope SanScope(this); llvm::Value *Zero = llvm::Constant::getNullValue(Size->getType()); llvm::Constant *StaticArgs[] = { EmitCheckSourceLocation(size->getLocStart()), @@ -1637,11 +1640,26 @@ llvm::Value *CodeGenFunction::EmitFieldA CodeGenFunction::CGCapturedStmtInfo::~CGCapturedStmtInfo() { } +CodeGenFunction::SanitizerScope::SanitizerScope(CodeGenFunction *CGF) + : CGF(CGF) { + assert(!CGF->IsSanitizerScope); + CGF->IsSanitizerScope = true; +} + +CodeGenFunction::SanitizerScope::~SanitizerScope() { + CGF->IsSanitizerScope = false; +} + void CodeGenFunction::InsertHelper(llvm::Instruction *I, const llvm::Twine &Name, llvm::BasicBlock *BB, llvm::BasicBlock::iterator InsertPt) const { LoopStack.InsertHelper(I); + if (IsSanitizerScope) { + I->setMetadata( + CGM.getModule().getMDKindID("nosanitize"), + llvm::MDNode::get(CGM.getLLVMContext(), ArrayRef<llvm::Value *>())); + } } template <bool PreserveNames> Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=213291&r1=213290&r2=213291&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original) +++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Thu Jul 17 13:46:27 2014 @@ -247,6 +247,17 @@ public: /// \brief Sanitizer options to use for this function. const SanitizerOptions *SanOpts; + /// \brief True if CodeGen currently emits code implementing sanitizer checks. + bool IsSanitizerScope; + + /// \brief RAII object to set/unset CodeGenFunction::IsSanitizerScope. + class SanitizerScope { + CodeGenFunction *CGF; + public: + SanitizerScope(CodeGenFunction *CGF); + ~SanitizerScope(); + }; + /// In ARC, whether we should autorelease the return value. bool AutoreleaseResult; Modified: cfe/trunk/test/CodeGen/catch-undef-behavior.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/catch-undef-behavior.c?rev=213291&r1=213290&r2=213291&view=diff ============================================================================== --- cfe/trunk/test/CodeGen/catch-undef-behavior.c (original) +++ cfe/trunk/test/CodeGen/catch-undef-behavior.c Thu Jul 17 13:46:27 2014 @@ -49,7 +49,7 @@ void foo() { // CHECK-TRAP-NEXT: %[[CHECK2:.*]] = icmp eq i64 %[[MISALIGN]], 0 // CHECK: %[[OK:.*]] = and i1 %[[CHECK01]], %[[CHECK2]] - // CHECK-NEXT: br i1 %[[OK]], {{.*}} !prof ![[WEIGHT_MD:.*]] + // CHECK-NEXT: br i1 %[[OK]], {{.*}} !prof ![[WEIGHT_MD:.*]], !nosanitize // CHECK-TRAP: %[[OK:.*]] = and i1 %[[CHECK01]], %[[CHECK2]] // CHECK-TRAP-NEXT: br i1 %[[OK]], {{.*}} @@ -311,7 +311,7 @@ int long_double_int_overflow(long double // CHECK: %[[LE:.*]] = fcmp olt x86_fp80 %[[F]], 0xK401E8000000000000000 // CHECK: and i1 %[[GE]], %[[LE]] - // CHECK: store x86_fp80 %[[F]], x86_fp80* %[[ALLOCA:.*]] + // CHECK: store x86_fp80 %[[F]], x86_fp80* %[[ALLOCA:.*]], !nosanitize // CHECK: %[[ARG:.*]] = ptrtoint x86_fp80* %[[ALLOCA]] to i64 // CHECK: call void @__ubsan_handle_float_cast_overflow({{.*}}, i64 %[[ARG]] _______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
