Skip to content

Commit 275f30d

Browse files
jtmott-intelgburgessiv
authored andcommitted
[clang] Change builtin object size when subobject is invalid
Motivating example: ``` struct { int v[10]; } t[10]; __builtin_object_size( &t[0].v[11], // access past end of subobject 1 // request remaining bytes of closest surrounding // subobject ); ``` In GCC, this returns 0. https://godbolt.org/z/7TeGs7 In current clang, however, this returns 356, the number of bytes remaining in the whole variable, as if the `type` was 0 instead of 1. https://godbolt.org/z/6Kffox This patch checks for the specific case where we're requesting a subobject's size (type 1) but the subobject is invalid. Differential Revision: https://reviews.llvm.org/D92892
1 parent 36c4dc9 commit 275f30d

File tree

2 files changed

+8
-8
lines changed

2 files changed

+8
-8
lines changed

clang/lib/AST/ExprConstant.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11408,9 +11408,9 @@ static bool tryEvaluateBuiltinObjectSize(const Expr *E, unsigned Type,
1140811408
return false;
1140911409
}
1141011410

11411-
// If we point to before the start of the object, there are no accessible
11412-
// bytes.
11413-
if (LVal.getLValueOffset().isNegative()) {
11411+
// If we point outside of the object, there are no accessible bytes.
11412+
if (LVal.getLValueOffset().isNegative() ||
11413+
((Type & 1) && !LVal.Designator.isValidSubobject())) {
1141411414
Size = 0;
1141511415
return true;
1141611416
}

clang/test/CodeGen/object-size.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -310,7 +310,7 @@ void test24() {
310310
void test25() {
311311
// CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* {{.*}}, i1 false, i1 true, i1
312312
gi = OBJECT_SIZE_BUILTIN((void*)0x1000, 0);
313-
// CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* {{.*}}, i1 false, i1 true, i1
313+
// CHECK: store i32 0
314314
gi = OBJECT_SIZE_BUILTIN((void*)0x1000, 1);
315315
// CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* {{.*}}, i1 true, i1 true, i1
316316
gi = OBJECT_SIZE_BUILTIN((void*)0x1000, 2);
@@ -321,7 +321,7 @@ void test25() {
321321

322322
// CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* {{.*}}, i1 false, i1 true, i1
323323
gi = OBJECT_SIZE_BUILTIN((void*)0 + 0x1000, 0);
324-
// CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* {{.*}}, i1 false, i1 true, i1
324+
// CHECK: store i32 0
325325
gi = OBJECT_SIZE_BUILTIN((void*)0 + 0x1000, 1);
326326
// CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* {{.*}}, i1 true, i1 true, i1
327327
gi = OBJECT_SIZE_BUILTIN((void*)0 + 0x1000, 2);
@@ -337,7 +337,7 @@ void test26() {
337337

338338
// CHECK: store i32 316
339339
gi = OBJECT_SIZE_BUILTIN(&t[1].v[11], 0);
340-
// CHECK: store i32 312
340+
// CHECK: store i32 0
341341
gi = OBJECT_SIZE_BUILTIN(&t[1].v[12], 1);
342342
// CHECK: store i32 308
343343
gi = OBJECT_SIZE_BUILTIN(&t[1].v[13], 2);
@@ -433,7 +433,7 @@ void test29(struct DynStructVar *dv, struct DynStruct0 *d0,
433433

434434
// CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true, i1
435435
gi = OBJECT_SIZE_BUILTIN(d0->snd, 0);
436-
// CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true, i1
436+
// CHECK: store i32 0
437437
gi = OBJECT_SIZE_BUILTIN(d0->snd, 1);
438438
// CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 true, i1 true, i1
439439
gi = OBJECT_SIZE_BUILTIN(d0->snd, 2);
@@ -518,7 +518,7 @@ void test31() {
518518
// CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true, i1
519519
gi = OBJECT_SIZE_BUILTIN(&ds1[9].snd[0], 1);
520520

521-
// CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true, i1
521+
// CHECK: store i32 0
522522
gi = OBJECT_SIZE_BUILTIN(&ds0[9].snd[0], 1);
523523

524524
// CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true, i1

0 commit comments

Comments
 (0)