diff options
| author | Alexey Samsonov <vonosmas@gmail.com> | 2015-03-05 21:57:35 +0000 |
|---|---|---|
| committer | Alexey Samsonov <vonosmas@gmail.com> | 2015-03-05 21:57:35 +0000 |
| commit | 48a9db034a321bdec2a050ec8131b1597a4f9c55 (patch) | |
| tree | 2f844fde86331e3cc7107eceeada2e0c60fbadd5 /clang/lib/CodeGen/CGExprScalar.cpp | |
| parent | 302404b2772a6d8cb290958784fb4d1414f5dd35 (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.cpp | 60 |
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"); |
