r221635 - Propagate SanitizerKind into CodeGenFunction::EmitCheck() call.
Alexey Samsonov
vonosmas at gmail.com
Mon Nov 10 14:27:30 PST 2014
Author: samsonov
Date: Mon Nov 10 16:27:30 2014
New Revision: 221635
URL: http://llvm.org/viewvc/llvm-project?rev=221635&view=rev
Log:
Propagate SanitizerKind into CodeGenFunction::EmitCheck() call.
Make sure CodeGenFunction::EmitCheck() knows which sanitizer
it emits check for. Make CheckRecoverableKind enum an
implementation detail and move it away from header.
Currently CheckRecoverableKind is determined by the type of
sanitizer ("unreachable" and "return" are unrecoverable,
"vptr" is always-recoverable, all the rest are recoverable).
This will change in future if we allow to specify which sanitizers
are recoverable, and which are not by -fsanitize-recover= flag.
No functionality change.
Modified:
cfe/trunk/lib/CodeGen/CGBuiltin.cpp
cfe/trunk/lib/CodeGen/CGCall.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
Modified: cfe/trunk/lib/CodeGen/CGBuiltin.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGBuiltin.cpp?rev=221635&r1=221634&r2=221635&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGBuiltin.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGBuiltin.cpp Mon Nov 10 16:27:30 2014
@@ -476,8 +476,8 @@ RValue CodeGenFunction::EmitBuiltinExpr(
if (SanOpts.has(SanitizerKind::Unreachable)) {
SanitizerScope SanScope(this);
EmitCheck(Builder.getFalse(), "builtin_unreachable",
- EmitCheckSourceLocation(E->getExprLoc()),
- None, CRK_Unrecoverable);
+ EmitCheckSourceLocation(E->getExprLoc()), None,
+ SanitizerKind::Unreachable);
} else
Builder.CreateUnreachable();
Modified: cfe/trunk/lib/CodeGen/CGCall.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCall.cpp?rev=221635&r1=221634&r2=221635&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGCall.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGCall.cpp Mon Nov 10 16:27:30 2014
@@ -2300,7 +2300,8 @@ void CodeGenFunction::EmitFunctionEpilog
EmitCheckSourceLocation(EndLoc),
EmitCheckSourceLocation(RetNNAttr->getLocation()),
};
- EmitCheck(Cond, "nonnull_return", StaticData, None, CRK_Recoverable);
+ EmitCheck(Cond, "nonnull_return", StaticData, None,
+ SanitizerKind::ReturnsNonnullAttribute);
}
}
Ret = Builder.CreateRet(RV);
@@ -2636,7 +2637,7 @@ static void emitNonNullArgCheck(CodeGenF
llvm::ConstantInt::get(CGF.Int32Ty, ArgNo + 1),
};
CGF.EmitCheck(Cond, "nonnull_arg", StaticData, None,
- CodeGenFunction::CRK_Recoverable);
+ SanitizerKind::NonnullAttribute);
}
void CodeGenFunction::EmitCallArgs(CallArgList &Args,
Modified: cfe/trunk/lib/CodeGen/CGExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=221635&r1=221634&r2=221635&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExpr.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExpr.cpp Mon Nov 10 16:27:30 2014
@@ -475,6 +475,7 @@ void CodeGenFunction::EmitTypeCheck(Type
if (Address->getType()->getPointerAddressSpace())
return;
+ SmallVector<SanitizerKind, 3> Kinds;
SanitizerScope SanScope(this);
llvm::Value *Cond = nullptr;
@@ -496,6 +497,8 @@ void CodeGenFunction::EmitTypeCheck(Type
Builder.CreateCondBr(Cond, Rest, Done);
EmitBlock(Rest);
Cond = nullptr;
+ } else {
+ Kinds.push_back(SanitizerKind::Null);
}
}
@@ -514,6 +517,7 @@ void CodeGenFunction::EmitTypeCheck(Type
Builder.CreateICmpUGE(Builder.CreateCall2(F, CastAddr, Min),
llvm::ConstantInt::get(IntPtrTy, Size));
Cond = Cond ? Builder.CreateAnd(Cond, LargeEnough) : LargeEnough;
+ Kinds.push_back(SanitizerKind::ObjectSize);
}
uint64_t AlignVal = 0;
@@ -531,6 +535,7 @@ void CodeGenFunction::EmitTypeCheck(Type
llvm::Value *Aligned =
Builder.CreateICmpEQ(Align, llvm::ConstantInt::get(IntPtrTy, 0));
Cond = Cond ? Builder.CreateAnd(Cond, Aligned) : Aligned;
+ Kinds.push_back(SanitizerKind::Alignment);
}
}
@@ -541,7 +546,7 @@ void CodeGenFunction::EmitTypeCheck(Type
llvm::ConstantInt::get(SizeTy, AlignVal),
llvm::ConstantInt::get(Int8Ty, TCK)
};
- EmitCheck(Cond, "type_mismatch", StaticData, Address, CRK_Recoverable);
+ EmitCheck(Cond, "type_mismatch", StaticData, Address, Kinds);
}
// If possible, check that the vptr indicates that there is a subobject of
@@ -606,9 +611,8 @@ void CodeGenFunction::EmitTypeCheck(Type
llvm::ConstantInt::get(Int8Ty, TCK)
};
llvm::Value *DynamicData[] = { Address, Hash };
- EmitCheck(Builder.CreateICmpEQ(CacheVal, Hash),
- "dynamic_type_cache_miss", StaticData, DynamicData,
- CRK_AlwaysRecoverable);
+ EmitCheck(Builder.CreateICmpEQ(CacheVal, Hash), "dynamic_type_cache_miss",
+ StaticData, DynamicData, SanitizerKind::Vptr);
}
}
@@ -696,7 +700,8 @@ void CodeGenFunction::EmitBoundsCheck(co
};
llvm::Value *Check = Accessed ? Builder.CreateICmpULT(IndexVal, BoundVal)
: Builder.CreateICmpULE(IndexVal, BoundVal);
- EmitCheck(Check, "out_of_bounds", StaticData, Index, CRK_Recoverable);
+ EmitCheck(Check, "out_of_bounds", StaticData, Index,
+ SanitizerKind::ArrayBounds);
}
@@ -1151,8 +1156,11 @@ llvm::Value *CodeGenFunction::EmitLoadOf
CGM.DecorateInstruction(Load, TBAAPath, false/*ConvertTypeToTag*/);
}
- if ((SanOpts.has(SanitizerKind::Bool) && hasBooleanRepresentation(Ty)) ||
- (SanOpts.has(SanitizerKind::Enum) && Ty->getAs<EnumType>())) {
+ bool NeedsBoolCheck =
+ SanOpts.has(SanitizerKind::Bool) && hasBooleanRepresentation(Ty);
+ bool NeedsEnumCheck =
+ SanOpts.has(SanitizerKind::Enum) && Ty->getAs<EnumType>();
+ if (NeedsBoolCheck || NeedsEnumCheck) {
SanitizerScope SanScope(this);
llvm::APInt Min, End;
if (getRangeForType(*this, Ty, Min, End, true)) {
@@ -1173,7 +1181,7 @@ llvm::Value *CodeGenFunction::EmitLoadOf
EmitCheckTypeDescriptor(Ty)
};
EmitCheck(Check, "load_invalid_value", StaticArgs, EmitCheckValue(Load),
- CRK_Recoverable);
+ NeedsEnumCheck ? SanitizerKind::Enum : SanitizerKind::Bool);
}
} else if (CGM.getCodeGenOpts().OptimizationLevel > 0)
if (llvm::MDNode *RangeInfo = getRangeForLoadFromType(Ty))
@@ -2169,14 +2177,45 @@ llvm::Constant *CodeGenFunction::EmitChe
return llvm::ConstantStruct::getAnon(Data);
}
+namespace {
+/// \brief Specify under what conditions this check can be recovered
+enum class CheckRecoverableKind {
+ /// Always terminate program execution if this check fails
+ Unrecoverable,
+ /// Check supports recovering, allows user to specify which
+ Recoverable,
+ /// Runtime conditionally aborts, always need to support recovery.
+ AlwaysRecoverable
+};
+}
+
+static CheckRecoverableKind getRecoverableKind(SanitizerKind Kind) {
+ switch (Kind) {
+ case SanitizerKind::Vptr:
+ return CheckRecoverableKind::AlwaysRecoverable;
+ case SanitizerKind::Return:
+ case SanitizerKind::Unreachable:
+ return CheckRecoverableKind::Unrecoverable;
+ default:
+ return CheckRecoverableKind::Recoverable;
+ }
+}
+
void CodeGenFunction::EmitCheck(llvm::Value *Checked, StringRef CheckName,
ArrayRef<llvm::Constant *> StaticArgs,
ArrayRef<llvm::Value *> DynamicArgs,
- CheckRecoverableKind RecoverKind) {
+ ArrayRef<SanitizerKind> Kinds) {
assert(IsSanitizerScope);
+ assert(Kinds.size() > 0);
+ CheckRecoverableKind RecoverKind = getRecoverableKind(Kinds[0]);
+ for (int i = 1, n = Kinds.size(); i < n; ++i)
+ assert(RecoverKind == getRecoverableKind(Kinds[i]) &&
+ "All recoverable kinds in a single check must be same!");
+ for (auto Kind : Kinds)
+ assert(SanOpts.has(Kind));
if (CGM.getCodeGenOpts().SanitizeUndefinedTrapOnError) {
- assert (RecoverKind != CRK_AlwaysRecoverable &&
+ assert (RecoverKind != CheckRecoverableKind::AlwaysRecoverable &&
"Runtime call required for AlwaysRecoverable kind!");
return EmitTrapCheck(Checked);
}
@@ -2217,8 +2256,8 @@ void CodeGenFunction::EmitCheck(llvm::Va
ArgTypes.push_back(IntPtrTy);
}
- bool Recover = RecoverKind == CRK_AlwaysRecoverable ||
- (RecoverKind == CRK_Recoverable &&
+ bool Recover = RecoverKind == CheckRecoverableKind::AlwaysRecoverable ||
+ (RecoverKind == CheckRecoverableKind::Recoverable &&
CGM.getCodeGenOpts().SanitizeRecover);
llvm::FunctionType *FnType =
@@ -2231,7 +2270,7 @@ void CodeGenFunction::EmitCheck(llvm::Va
B.addAttribute(llvm::Attribute::UWTable);
// Checks that have two variants use a suffix to differentiate them
- bool NeedsAbortSuffix = RecoverKind != CRK_Unrecoverable &&
+ bool NeedsAbortSuffix = RecoverKind != CheckRecoverableKind::Unrecoverable &&
!CGM.getCodeGenOpts().SanitizeRecover;
std::string FunctionName = ("__ubsan_handle_" + CheckName +
(NeedsAbortSuffix? "_abort" : "")).str();
@@ -3260,11 +3299,8 @@ RValue CodeGenFunction::EmitCall(QualTyp
EmitCheckSourceLocation(E->getLocStart()),
EmitCheckTypeDescriptor(CalleeType)
};
- EmitCheck(CalleeRTTIMatch,
- "function_type_mismatch",
- StaticData,
- Callee,
- CRK_Recoverable);
+ EmitCheck(CalleeRTTIMatch, "function_type_mismatch", StaticData, Callee,
+ SanitizerKind::Function);
Builder.CreateBr(Cont);
EmitBlock(Cont);
Modified: cfe/trunk/lib/CodeGen/CGExprScalar.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprScalar.cpp?rev=221635&r1=221634&r2=221635&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprScalar.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprScalar.cpp Mon Nov 10 16:27:30 2014
@@ -85,7 +85,8 @@ public:
return CGF.EmitCheckedLValue(E, TCK);
}
- void EmitBinOpCheck(Value *Check, const BinOpInfo &Info);
+ void EmitBinOpCheck(Value *Check, const BinOpInfo &Info,
+ ArrayRef<SanitizerKind> Kinds);
Value *EmitLoadOfLValue(LValue LV, SourceLocation Loc) {
return CGF.EmitLoadOfLValue(LV, Loc).getScalarVal();
@@ -726,7 +727,7 @@ void ScalarExprEmitter::EmitFloatConvers
CGF.EmitCheckTypeDescriptor(DstType)
};
CGF.EmitCheck(Check, "float_cast_overflow", StaticArgs, OrigSrc,
- CodeGenFunction::CRK_Recoverable);
+ SanitizerKind::FloatCastOverflow);
}
/// EmitScalarConversion - Emit a conversion from the specified type to the
@@ -885,7 +886,8 @@ Value *ScalarExprEmitter::EmitNullValue(
/// \brief Emit a sanitization check for the given "binary" operation (which
/// 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) {
+void ScalarExprEmitter::EmitBinOpCheck(Value *Check, const BinOpInfo &Info,
+ ArrayRef<SanitizerKind> Kinds) {
assert(CGF.IsSanitizerScope);
StringRef CheckName;
SmallVector<llvm::Constant *, 4> StaticData;
@@ -915,7 +917,7 @@ void ScalarExprEmitter::EmitBinOpCheck(V
CheckName = "divrem_overflow";
StaticData.push_back(CGF.EmitCheckTypeDescriptor(Info.Ty));
} else {
- // Signed arithmetic overflow (+, -, *).
+ // Arithmetic overflow (+, -, *).
switch (Opcode) {
case BO_Add: CheckName = "add_overflow"; break;
case BO_Sub: CheckName = "sub_overflow"; break;
@@ -928,8 +930,7 @@ void ScalarExprEmitter::EmitBinOpCheck(V
DynamicData.push_back(Info.RHS);
}
- CGF.EmitCheck(Check, CheckName, StaticData, DynamicData,
- CodeGenFunction::CRK_Recoverable);
+ CGF.EmitCheck(Check, CheckName, StaticData, DynamicData, Kinds);
}
//===----------------------------------------------------------------------===//
@@ -2179,9 +2180,12 @@ Value *ScalarExprEmitter::EmitCompoundAs
void ScalarExprEmitter::EmitUndefinedBehaviorIntegerDivAndRemCheck(
const BinOpInfo &Ops, llvm::Value *Zero, bool isDiv) {
llvm::Value *Cond = nullptr;
+ SmallVector<SanitizerKind, 2> Kinds;
- if (CGF.SanOpts.has(SanitizerKind::IntegerDivideByZero))
+ if (CGF.SanOpts.has(SanitizerKind::IntegerDivideByZero)) {
Cond = Builder.CreateICmpNE(Ops.RHS, Zero);
+ Kinds.push_back(SanitizerKind::IntegerDivideByZero);
+ }
if (CGF.SanOpts.has(SanitizerKind::SignedIntegerOverflow) &&
Ops.Ty->hasSignedIntegerRepresentation()) {
@@ -2195,10 +2199,11 @@ void ScalarExprEmitter::EmitUndefinedBeh
llvm::Value *RHSCmp = Builder.CreateICmpNE(Ops.RHS, NegOne);
llvm::Value *Overflow = Builder.CreateOr(LHSCmp, RHSCmp, "or");
Cond = Cond ? Builder.CreateAnd(Cond, Overflow, "and") : Overflow;
+ Kinds.push_back(SanitizerKind::SignedIntegerOverflow);
}
if (Cond)
- EmitBinOpCheck(Cond, Ops);
+ EmitBinOpCheck(Cond, Ops, Kinds);
}
Value *ScalarExprEmitter::EmitDiv(const BinOpInfo &Ops) {
@@ -2212,7 +2217,8 @@ Value *ScalarExprEmitter::EmitDiv(const
} else if (CGF.SanOpts.has(SanitizerKind::FloatDivideByZero) &&
Ops.Ty->isRealFloatingType()) {
llvm::Value *Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
- EmitBinOpCheck(Builder.CreateFCmpUNE(Ops.RHS, Zero), Ops);
+ EmitBinOpCheck(Builder.CreateFCmpUNE(Ops.RHS, Zero), Ops,
+ SanitizerKind::FloatDivideByZero);
}
}
@@ -2297,7 +2303,9 @@ Value *ScalarExprEmitter::EmitOverflowCh
// runtime. Otherwise, this is a -ftrapv check, so just emit a trap.
if (!isSigned || CGF.SanOpts.has(SanitizerKind::SignedIntegerOverflow)) {
CodeGenFunction::SanitizerScope SanScope(&CGF);
- EmitBinOpCheck(Builder.CreateNot(overflow), Ops);
+ EmitBinOpCheck(Builder.CreateNot(overflow), Ops,
+ isSigned ? SanitizerKind::SignedIntegerOverflow
+ : SanitizerKind::UnsignedIntegerOverflow);
} else
CGF.EmitTrapCheck(Builder.CreateNot(overflow));
return result;
@@ -2687,7 +2695,7 @@ Value *ScalarExprEmitter::EmitShl(const
Valid = P;
}
- EmitBinOpCheck(Valid, Ops);
+ EmitBinOpCheck(Valid, Ops, SanitizerKind::Shift);
}
// OpenCL 6.3j: shift values are effectively % word size of LHS.
if (CGF.getLangOpts().OpenCL)
@@ -2706,7 +2714,9 @@ Value *ScalarExprEmitter::EmitShr(const
if (CGF.SanOpts.has(SanitizerKind::Shift) && !CGF.getLangOpts().OpenCL &&
isa<llvm::IntegerType>(Ops.LHS->getType())) {
CodeGenFunction::SanitizerScope SanScope(&CGF);
- EmitBinOpCheck(Builder.CreateICmpULE(RHS, GetWidthMinusOneValue(Ops.LHS, RHS)), Ops);
+ EmitBinOpCheck(
+ Builder.CreateICmpULE(RHS, GetWidthMinusOneValue(Ops.LHS, RHS)), Ops,
+ SanitizerKind::Shift);
}
// OpenCL 6.3j: shift values are effectively % word size of LHS.
Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.cpp?rev=221635&r1=221634&r2=221635&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.cpp Mon Nov 10 16:27:30 2014
@@ -900,8 +900,8 @@ void CodeGenFunction::GenerateCode(Globa
if (SanOpts.has(SanitizerKind::Return)) {
SanitizerScope SanScope(this);
EmitCheck(Builder.getFalse(), "missing_return",
- EmitCheckSourceLocation(FD->getLocation()),
- None, CRK_Unrecoverable);
+ EmitCheckSourceLocation(FD->getLocation()), None,
+ SanitizerKind::Return);
} else if (CGM.getCodeGenOpts().OptimizationLevel == 0)
Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::trap));
Builder.CreateUnreachable();
@@ -1562,7 +1562,7 @@ void CodeGenFunction::EmitVariablyModifi
};
EmitCheck(Builder.CreateICmpSGT(Size, Zero),
"vla_bound_not_positive", StaticArgs, Size,
- CRK_Recoverable);
+ SanitizerKind::VLABound);
}
// Always zexting here would be wrong if it weren't
Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=221635&r1=221634&r2=221635&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Mon Nov 10 16:27:30 2014
@@ -2649,23 +2649,13 @@ public:
/// passing to a runtime sanitizer handler.
llvm::Constant *EmitCheckSourceLocation(SourceLocation Loc);
- /// \brief Specify under what conditions this check can be recovered
- enum CheckRecoverableKind {
- /// Always terminate program execution if this check fails
- CRK_Unrecoverable,
- /// Check supports recovering, allows user to specify which
- CRK_Recoverable,
- /// Runtime conditionally aborts, always need to support recovery.
- CRK_AlwaysRecoverable
- };
-
/// \brief Create a basic block that will call a handler function in a
/// sanitizer runtime with the provided arguments, and create a conditional
/// branch to it.
void EmitCheck(llvm::Value *Checked, StringRef CheckName,
ArrayRef<llvm::Constant *> StaticArgs,
ArrayRef<llvm::Value *> DynamicArgs,
- CheckRecoverableKind Recoverable);
+ ArrayRef<SanitizerKind> Kinds);
/// \brief Create a basic block that will call the trap intrinsic, and emit a
/// conditional branch to it, for the -ftrapv checks.
More information about the cfe-commits
mailing list