summaryrefslogtreecommitdiff
path: root/clang/lib/CodeGen/CGExprScalar.cpp
diff options
context:
space:
mode:
authorAlexey Samsonov <vonosmas@gmail.com>2015-03-05 21:57:35 +0000
committerAlexey Samsonov <vonosmas@gmail.com>2015-03-05 21:57:35 +0000
commit48a9db034a321bdec2a050ec8131b1597a4f9c55 (patch)
tree2f844fde86331e3cc7107eceeada2e0c60fbadd5 /clang/lib/CodeGen/CGExprScalar.cpp
parent302404b2772a6d8cb290958784fb4d1414f5dd35 (diff)
Revert "[UBSan] Split -fsanitize=shift into -fsanitize=shift-base and -fsanitize=shift-exponent."
It's not that easy. If we're only checking -fsanitize=shift-base we still need to verify that exponent has sane value, otherwise UBSan-inserted checks for base will contain undefined behavior themselves. llvm-svn: 231409
Diffstat (limited to 'clang/lib/CodeGen/CGExprScalar.cpp')
-rw-r--r--clang/lib/CodeGen/CGExprScalar.cpp60
1 files changed, 28 insertions, 32 deletions
diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp
index 3544ce57366a..dc12dd84249b 100644
--- a/clang/lib/CodeGen/CGExprScalar.cpp
+++ b/clang/lib/CodeGen/CGExprScalar.cpp
@@ -2664,30 +2664,21 @@ Value *ScalarExprEmitter::EmitShl(const BinOpInfo &Ops) {
if (Ops.LHS->getType() != RHS->getType())
RHS = Builder.CreateIntCast(RHS, Ops.LHS->getType(), false, "sh_prom");
- // OpenCL 6.3j: shift values are effectively % word size of LHS.
- if (CGF.getLangOpts().OpenCL)
- RHS =
- Builder.CreateAnd(RHS, GetWidthMinusOneValue(Ops.LHS, RHS), "shl.mask");
- else if ((CGF.SanOpts.has(SanitizerKind::ShiftBase) ||
- CGF.SanOpts.has(SanitizerKind::ShiftExponent)) &&
- isa<llvm::IntegerType>(Ops.LHS->getType())) {
+ if (CGF.SanOpts.has(SanitizerKind::Shift) && !CGF.getLangOpts().OpenCL &&
+ isa<llvm::IntegerType>(Ops.LHS->getType())) {
CodeGenFunction::SanitizerScope SanScope(&CGF);
- SmallVector<std::pair<Value *, SanitizerKind>, 2> Checks;
- llvm::Value *WidthMinusOne = nullptr;
-
- if (CGF.SanOpts.has(SanitizerKind::ShiftExponent)) {
- WidthMinusOne = GetWidthMinusOneValue(Ops.LHS, RHS);
- llvm::Value *ValidExponent = Builder.CreateICmpULE(RHS, WidthMinusOne);
- Checks.push_back(
- std::make_pair(ValidExponent, SanitizerKind::ShiftExponent));
- }
+ llvm::Value *WidthMinusOne = GetWidthMinusOneValue(Ops.LHS, RHS);
+ llvm::Value *Valid = Builder.CreateICmpULE(RHS, WidthMinusOne);
+
+ if (Ops.Ty->hasSignedIntegerRepresentation()) {
+ llvm::BasicBlock *Orig = Builder.GetInsertBlock();
+ llvm::BasicBlock *Cont = CGF.createBasicBlock("cont");
+ llvm::BasicBlock *CheckBitsShifted = CGF.createBasicBlock("check");
+ Builder.CreateCondBr(Valid, CheckBitsShifted, Cont);
- if (CGF.SanOpts.has(SanitizerKind::ShiftBase) &&
- Ops.Ty->hasSignedIntegerRepresentation()) {
- if (WidthMinusOne == nullptr)
- WidthMinusOne = GetWidthMinusOneValue(Ops.LHS, RHS);
// Check whether we are shifting any non-zero bits off the top of the
// integer.
+ CGF.EmitBlock(CheckBitsShifted);
llvm::Value *BitsShiftedOff =
Builder.CreateLShr(Ops.LHS,
Builder.CreateSub(WidthMinusOne, RHS, "shl.zeros",
@@ -2702,14 +2693,19 @@ Value *ScalarExprEmitter::EmitShl(const BinOpInfo &Ops) {
BitsShiftedOff = Builder.CreateLShr(BitsShiftedOff, One);
}
llvm::Value *Zero = llvm::ConstantInt::get(BitsShiftedOff->getType(), 0);
- llvm::Value *ValidBase = Builder.CreateICmpEQ(BitsShiftedOff, Zero);
-
- Checks.push_back(std::make_pair(ValidBase, SanitizerKind::ShiftBase));
+ llvm::Value *SecondCheck = Builder.CreateICmpEQ(BitsShiftedOff, Zero);
+ CGF.EmitBlock(Cont);
+ llvm::PHINode *P = Builder.CreatePHI(Valid->getType(), 2);
+ P->addIncoming(Valid, Orig);
+ P->addIncoming(SecondCheck, CheckBitsShifted);
+ Valid = P;
}
- if (!Checks.empty())
- EmitBinOpCheck(Checks, Ops);
+ EmitBinOpCheck(std::make_pair(Valid, SanitizerKind::Shift), Ops);
}
+ // OpenCL 6.3j: shift values are effectively % word size of LHS.
+ if (CGF.getLangOpts().OpenCL)
+ RHS = Builder.CreateAnd(RHS, GetWidthMinusOneValue(Ops.LHS, RHS), "shl.mask");
return Builder.CreateShl(Ops.LHS, RHS, "shl");
}
@@ -2721,18 +2717,18 @@ Value *ScalarExprEmitter::EmitShr(const BinOpInfo &Ops) {
if (Ops.LHS->getType() != RHS->getType())
RHS = Builder.CreateIntCast(RHS, Ops.LHS->getType(), false, "sh_prom");
- // OpenCL 6.3j: shift values are effectively % word size of LHS.
- if (CGF.getLangOpts().OpenCL)
- RHS =
- Builder.CreateAnd(RHS, GetWidthMinusOneValue(Ops.LHS, RHS), "shr.mask");
- else if (CGF.SanOpts.has(SanitizerKind::ShiftExponent) &&
- isa<llvm::IntegerType>(Ops.LHS->getType())) {
+ if (CGF.SanOpts.has(SanitizerKind::Shift) && !CGF.getLangOpts().OpenCL &&
+ isa<llvm::IntegerType>(Ops.LHS->getType())) {
CodeGenFunction::SanitizerScope SanScope(&CGF);
llvm::Value *Valid =
Builder.CreateICmpULE(RHS, GetWidthMinusOneValue(Ops.LHS, RHS));
- EmitBinOpCheck(std::make_pair(Valid, SanitizerKind::ShiftExponent), Ops);
+ EmitBinOpCheck(std::make_pair(Valid, SanitizerKind::Shift), Ops);
}
+ // OpenCL 6.3j: shift values are effectively % word size of LHS.
+ if (CGF.getLangOpts().OpenCL)
+ RHS = Builder.CreateAnd(RHS, GetWidthMinusOneValue(Ops.LHS, RHS), "shr.mask");
+
if (Ops.Ty->hasUnsignedIntegerRepresentation())
return Builder.CreateLShr(Ops.LHS, RHS, "shr");
return Builder.CreateAShr(Ops.LHS, RHS, "shr");