[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