Skip to content

Commit 572b087

Browse files
committed
[clang] Add back -fsanitize=array-bounds workaround for size-1 array after -fstrict-flex-arrays change
Before C99 introduced flexible array member, common practice uses size-1 array to emulate FAM, e.g. python/cpython#94250 As a result, -fsanitize=array-bounds instrumentation skipped such structures as a workaround (from 539e4a7). D126864 accidentally dropped the workaround. Add it back with tests.
1 parent a83034e commit 572b087

File tree

2 files changed

+44
-2
lines changed

2 files changed

+44
-2
lines changed

clang/lib/CodeGen/CGExpr.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -931,8 +931,8 @@ static llvm::Value *getArrayIndexingBound(CodeGenFunction &CGF,
931931

932932
if (const auto *CE = dyn_cast<CastExpr>(Base)) {
933933
if (CE->getCastKind() == CK_ArrayToPointerDecay &&
934-
!CE->getSubExpr()->isFlexibleArrayMember(Context,
935-
StrictFlexArraysLevel)) {
934+
!CE->getSubExpr()->IgnoreParens()->isFlexibleArrayMember(
935+
Context, std::max(StrictFlexArraysLevel, 1))) {
936936
IndexedType = CE->getSubExpr()->getType();
937937
const ArrayType *AT = IndexedType->castAsArrayTypeUnsafe();
938938
if (const auto *CAT = dyn_cast<ConstantArrayType>(AT))
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// REQUIRES: x86-registered-target
2+
// RUN: %clang_cc1 -emit-llvm -triple x86_64 -fsanitize=array-bounds %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-STRICT-0
3+
// RUN: %clang_cc1 -emit-llvm -triple x86_64 -fsanitize=array-bounds -fstrict-flex-arrays=1 %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-STRICT-1
4+
// RUN: %clang_cc1 -emit-llvm -triple x86_64 -fsanitize=array-bounds -fstrict-flex-arrays=2 %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-STRICT-2
5+
6+
// Before flexible array member was added to C99, many projects use a
7+
// one-element array as the last emember of a structure as an alternative.
8+
// E.g. https://github.com/python/cpython/issues/94250
9+
// Suppress such errors with -fstrict-flex-arrays=0.
10+
struct One {
11+
int a[1];
12+
};
13+
struct Two {
14+
int a[2];
15+
};
16+
struct Three {
17+
int a[3];
18+
};
19+
20+
// CHECK-LABEL: define {{.*}} @test_one(
21+
int test_one(struct One *p, int i) {
22+
// CHECK-STRICT-0-NOT: @__ubsan
23+
// CHECK-STRICT-1-NOT: @__ubsan
24+
// CHECK-STRICT-2: call void @__ubsan_handle_out_of_bounds_abort(
25+
return p->a[i] + (p->a)[i];
26+
}
27+
28+
// CHECK-LABEL: define {{.*}} @test_two(
29+
int test_two(struct Two *p, int i) {
30+
// CHECK-STRICT-0: call void @__ubsan_handle_out_of_bounds_abort(
31+
// CHECK-STRICT-1: call void @__ubsan_handle_out_of_bounds_abort(
32+
// CHECK-STRICT-2: call void @__ubsan_handle_out_of_bounds_abort(
33+
return p->a[i] + (p->a)[i];
34+
}
35+
36+
// CHECK-LABEL: define {{.*}} @test_three(
37+
int test_three(struct Three *p, int i) {
38+
// CHECK-STRICT-0: call void @__ubsan_handle_out_of_bounds_abort(
39+
// CHECK-STRICT-1: call void @__ubsan_handle_out_of_bounds_abort(
40+
// CHECK-STRICT-2: call void @__ubsan_handle_out_of_bounds_abort(
41+
return p->a[i] + (p->a)[i];
42+
}

0 commit comments

Comments
 (0)