summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorRoman Lebedev <lebedev.ri@gmail.com>2019-09-06 14:18:49 +0000
committerRoman Lebedev <lebedev.ri@gmail.com>2019-09-06 14:18:49 +0000
commit624620ff57cd725af724fc760d3b51ce926c529f (patch)
tree985c2914eae3872331943152ea76af80978394b7 /clang/lib
parent06487b010d48c36c7714ee083ed38dff65711812 (diff)
downloadbcm5719-llvm-624620ff57cd725af724fc760d3b51ce926c529f.tar.gz
bcm5719-llvm-624620ff57cd725af724fc760d3b51ce926c529f.zip
[NFC][CodeGen][UBSan] EmitCheckedInBoundsGEP(): add some comments to pointer-overflow check
It's rather eye-twiching, some comments may help here.. This was originally part of https://reviews.llvm.org/D67122 llvm-svn: 371206
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/CodeGen/CGExprScalar.cpp26
1 files changed, 18 insertions, 8 deletions
diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp
index 3d082de2a14..1221527491e 100644
--- a/clang/lib/CodeGen/CGExprScalar.cpp
+++ b/clang/lib/CodeGen/CGExprScalar.cpp
@@ -4643,19 +4643,29 @@ Value *CodeGenFunction::EmitCheckedInBoundsGEP(Value *Ptr,
llvm::Value *ValidGEP;
auto *NoOffsetOverflow = Builder.CreateNot(OffsetOverflows);
if (SignedIndices) {
+ // GEP is computed as `unsigned base + signed offset`, therefore:
+ // * If offset was positive, then the computed pointer can not be
+ // [unsigned] less than the base pointer, unless it overflowed.
+ // * If offset was negative, then the computed pointer can not be
+ // [unsigned] greater than the bas pointere, unless it overflowed.
auto *PosOrZeroValid = Builder.CreateICmpUGE(ComputedGEP, IntPtr);
auto *PosOrZeroOffset = Builder.CreateICmpSGE(TotalOffset, Zero);
llvm::Value *NegValid = Builder.CreateICmpULT(ComputedGEP, IntPtr);
- ValidGEP = Builder.CreateAnd(
- Builder.CreateSelect(PosOrZeroOffset, PosOrZeroValid, NegValid),
- NoOffsetOverflow);
- } else if (!SignedIndices && !IsSubtraction) {
- auto *PosOrZeroValid = Builder.CreateICmpUGE(ComputedGEP, IntPtr);
- ValidGEP = Builder.CreateAnd(PosOrZeroValid, NoOffsetOverflow);
+ ValidGEP = Builder.CreateSelect(PosOrZeroOffset, PosOrZeroValid, NegValid);
+ } else if (!IsSubtraction) {
+ // GEP is computed as `unsigned base + unsigned offset`, therefore the
+ // computed pointer can not be [unsigned] less than base pointer,
+ // unless there was an overflow.
+ // Equivalent to `@llvm.uadd.with.overflow(%base, %offset)`.
+ ValidGEP = Builder.CreateICmpUGE(ComputedGEP, IntPtr);
} else {
- auto *NegOrZeroValid = Builder.CreateICmpULE(ComputedGEP, IntPtr);
- ValidGEP = Builder.CreateAnd(NegOrZeroValid, NoOffsetOverflow);
+ // GEP is computed as `unsigned base - unsigned offset`, therefore the
+ // computed pointer can not be [unsigned] greater than base pointer,
+ // unless there was an overflow.
+ // Equivalent to `@llvm.usub.with.overflow(%base, sub(0, %offset))`.
+ ValidGEP = Builder.CreateICmpULE(ComputedGEP, IntPtr);
}
+ ValidGEP = Builder.CreateAnd(ValidGEP, NoOffsetOverflow);
llvm::Constant *StaticArgs[] = {EmitCheckSourceLocation(Loc)};
// Pass the computed GEP to the runtime to avoid emitting poisoned arguments.
OpenPOWER on IntegriCloud