Skip to content

Commit 2ec5ced

Browse files
[llvm] Fix behavior of llvm.objectsize in presence of negative offset
When an object is located before it's allocation point, e.g. char a[10]; char* b = a[-3]; If we ask for the maximum amount of memory addressable from `b` through __builtin_object_size(b, 0) It is better to return -1, even if we actually know everything about the allocation point, than to return 0, which we currently do and that leads to sanitizer raising invalid/incorrect diagnostic.
1 parent 10feb40 commit 2ec5ced

File tree

2 files changed

+32
-8
lines changed

2 files changed

+32
-8
lines changed

llvm/lib/Analysis/MemoryBuiltins.cpp

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -564,8 +564,13 @@ Value *llvm::getFreedOperand(const CallBase *CB, const TargetLibraryInfo *TLI) {
564564
static APInt getSizeWithOverflow(const SizeOffsetAPInt &Data) {
565565
APInt Size = Data.Size;
566566
APInt Offset = Data.Offset;
567-
if (Offset.isNegative() || Size.ult(Offset))
568-
return APInt(Size.getBitWidth(), 0);
567+
568+
assert(!Offset.isNegative() &&
569+
"size for a pointer before the allocated object is ambiguous");
570+
571+
if (Size.ult(Offset))
572+
return APInt::getZero(Size.getBitWidth());
573+
569574
return Size - Offset;
570575
}
571576

@@ -580,6 +585,11 @@ bool llvm::getObjectSize(const Value *Ptr, uint64_t &Size, const DataLayout &DL,
580585
if (!Data.bothKnown())
581586
return false;
582587

588+
// We could compute an over-approximation in that situation, may be if
589+
// Opts.EvalMode == Max, but let's bee conservative and bail out.
590+
if (Data.Offset.isNegative())
591+
return false;
592+
583593
Size = getSizeWithOverflow(Data).getZExtValue();
584594
return true;
585595
}

llvm/test/Transforms/LowerConstantIntrinsics/objectsize_basic.ll

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -195,12 +195,26 @@ define i64 @out_of_bound_gep() {
195195
ret i64 %objsize
196196
}
197197

198-
define i64 @wrapping_gep() {
198+
define i64 @wrapping_gep(i1 %c) {
199199
; CHECK-LABEL: @wrapping_gep(
200200
; CHECK-NEXT: [[OBJ:%.*]] = alloca i8, i64 4, align 1
201+
; CHECK-NEXT: [[SLIDE:%.*]] = getelementptr i8, ptr [[OBJ]], i64 -9223372036854775807
202+
; CHECK-NEXT: [[SLIDE_BIS:%.*]] = getelementptr i8, ptr [[SLIDE]], i64 -9223372036854775808
203+
; CHECK-NEXT: ret i64 3
204+
;
205+
%obj = alloca i8, i64 4
206+
%slide = getelementptr i8, ptr %obj, i64 9223372036854775809
207+
%slide.bis = getelementptr i8, ptr %slide, i64 9223372036854775808
208+
%objsize = call i64 @llvm.objectsize.i64(ptr %slide.bis, i1 false, i1 false, i1 false)
209+
ret i64 %objsize
210+
}
211+
212+
define i64 @wrapping_gep_neg(i1 %c) {
213+
; CHECK-LABEL: @wrapping_gep_neg(
214+
; CHECK-NEXT: [[OBJ:%.*]] = alloca i8, i64 4, align 1
201215
; CHECK-NEXT: [[SLIDE:%.*]] = getelementptr i8, ptr [[OBJ]], i64 9223372036854775807
202216
; CHECK-NEXT: [[SLIDE_BIS:%.*]] = getelementptr i8, ptr [[SLIDE]], i64 9223372036854775807
203-
; CHECK-NEXT: ret i64 0
217+
; CHECK-NEXT: ret i64 -1
204218
;
205219
%obj = alloca i8, i64 4
206220
%slide = getelementptr i8, ptr %obj, i64 9223372036854775807
@@ -209,8 +223,8 @@ define i64 @wrapping_gep() {
209223
ret i64 %objsize
210224
}
211225

212-
define i64 @wrapping_gep_neg() {
213-
; CHECK-LABEL: @wrapping_gep_neg(
226+
define i64 @wrapping_gep_large_alloc(i1 %c) {
227+
; CHECK-LABEL: @wrapping_gep_large_alloc(
214228
; CHECK-NEXT: [[OBJ:%.*]] = alloca i8, i64 9223372036854775807, align 1
215229
; CHECK-NEXT: [[SLIDE:%.*]] = getelementptr i8, ptr [[OBJ]], i64 9223372036854775807
216230
; CHECK-NEXT: [[SLIDE_BIS:%.*]] = getelementptr i8, ptr [[SLIDE]], i64 3
@@ -251,11 +265,11 @@ define i64 @large_malloc() {
251265
ret i64 %objsize
252266
}
253267

254-
define i64 @out_of_bound_negative_gep() {
268+
define i64 @out_of_bound_negative_gep(i1 %c) {
255269
; CHECK-LABEL: @out_of_bound_negative_gep(
256270
; CHECK-NEXT: [[OBJ:%.*]] = alloca i8, i32 4, align 1
257271
; CHECK-NEXT: [[SLIDE:%.*]] = getelementptr i8, ptr [[OBJ]], i8 -8
258-
; CHECK-NEXT: ret i64 0
272+
; CHECK-NEXT: ret i64 -1
259273
;
260274
%obj = alloca i8, i32 4
261275
%slide = getelementptr i8, ptr %obj, i8 -8

0 commit comments

Comments
 (0)