[clang] 572b087 - [clang] Add back -fsanitize=array-bounds workaround for size-1 array after -fstrict-flex-arrays change
Fangrui Song via cfe-commits
cfe-commits at lists.llvm.org
Fri Jun 24 22:15:52 PDT 2022
Author: Fangrui Song
Date: 2022-06-24T22:15:47-07:00
New Revision: 572b08790a69f955ae0cbb1b4a7d4a215f15dad9
URL: https://github.com/llvm/llvm-project/commit/572b08790a69f955ae0cbb1b4a7d4a215f15dad9
DIFF: https://github.com/llvm/llvm-project/commit/572b08790a69f955ae0cbb1b4a7d4a215f15dad9.diff
LOG: [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. https://github.com/python/cpython/issues/94250
As a result, -fsanitize=array-bounds instrumentation skipped such structures
as a workaround (from 539e4a77bbabbc19f22b2bd24e04af2e432e599d).
D126864 accidentally dropped the workaround. Add it back with tests.
Added:
clang/test/CodeGen/bounds-checking-fma.c
Modified:
clang/lib/CodeGen/CGExpr.cpp
Removed:
################################################################################
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index df96be70800b..0fed82d3e68c 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -931,8 +931,8 @@ static llvm::Value *getArrayIndexingBound(CodeGenFunction &CGF,
if (const auto *CE = dyn_cast<CastExpr>(Base)) {
if (CE->getCastKind() == CK_ArrayToPointerDecay &&
- !CE->getSubExpr()->isFlexibleArrayMember(Context,
- StrictFlexArraysLevel)) {
+ !CE->getSubExpr()->IgnoreParens()->isFlexibleArrayMember(
+ Context, std::max(StrictFlexArraysLevel, 1))) {
IndexedType = CE->getSubExpr()->getType();
const ArrayType *AT = IndexedType->castAsArrayTypeUnsafe();
if (const auto *CAT = dyn_cast<ConstantArrayType>(AT))
diff --git a/clang/test/CodeGen/bounds-checking-fma.c b/clang/test/CodeGen/bounds-checking-fma.c
new file mode 100644
index 000000000000..fbc51dc7a5e1
--- /dev/null
+++ b/clang/test/CodeGen/bounds-checking-fma.c
@@ -0,0 +1,42 @@
+// REQUIRES: x86-registered-target
+// RUN: %clang_cc1 -emit-llvm -triple x86_64 -fsanitize=array-bounds %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-STRICT-0
+// 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
+// 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
+
+// Before flexible array member was added to C99, many projects use a
+// one-element array as the last emember of a structure as an alternative.
+// E.g. https://github.com/python/cpython/issues/94250
+// Suppress such errors with -fstrict-flex-arrays=0.
+struct One {
+ int a[1];
+};
+struct Two {
+ int a[2];
+};
+struct Three {
+ int a[3];
+};
+
+// CHECK-LABEL: define {{.*}} @test_one(
+int test_one(struct One *p, int i) {
+ // CHECK-STRICT-0-NOT: @__ubsan
+ // CHECK-STRICT-1-NOT: @__ubsan
+ // CHECK-STRICT-2: call void @__ubsan_handle_out_of_bounds_abort(
+ return p->a[i] + (p->a)[i];
+}
+
+// CHECK-LABEL: define {{.*}} @test_two(
+int test_two(struct Two *p, int i) {
+ // CHECK-STRICT-0: call void @__ubsan_handle_out_of_bounds_abort(
+ // CHECK-STRICT-1: call void @__ubsan_handle_out_of_bounds_abort(
+ // CHECK-STRICT-2: call void @__ubsan_handle_out_of_bounds_abort(
+ return p->a[i] + (p->a)[i];
+}
+
+// CHECK-LABEL: define {{.*}} @test_three(
+int test_three(struct Three *p, int i) {
+ // CHECK-STRICT-0: call void @__ubsan_handle_out_of_bounds_abort(
+ // CHECK-STRICT-1: call void @__ubsan_handle_out_of_bounds_abort(
+ // CHECK-STRICT-2: call void @__ubsan_handle_out_of_bounds_abort(
+ return p->a[i] + (p->a)[i];
+}
More information about the cfe-commits
mailing list