[clang] e0746a8 - [clang] cleanup -fstrict-flex-arrays implementation

via cfe-commits cfe-commits at lists.llvm.org
Thu Sep 1 06:10:23 PDT 2022


Author: serge-sans-paille
Date: 2022-09-01T15:06:21+02:00
New Revision: e0746a8a8d647ccee41accf16df895c9b03552c2

URL: https://github.com/llvm/llvm-project/commit/e0746a8a8d647ccee41accf16df895c9b03552c2
DIFF: https://github.com/llvm/llvm-project/commit/e0746a8a8d647ccee41accf16df895c9b03552c2.diff

LOG: [clang] cleanup -fstrict-flex-arrays implementation

This is a follow up to https://reviews.llvm.org/D126864, addressing some remaining
comments.

It also considers union with a single zero-length array field as FAM for each
value of -fstrict-flex-arrays.

Differential Revision: https://reviews.llvm.org/D132944

Added: 
    

Modified: 
    clang/include/clang/Driver/Options.td
    clang/lib/CodeGen/CGExpr.cpp
    clang/lib/Sema/SemaChecking.cpp
    clang/test/CodeGen/bounds-checking-fam.c
    clang/test/CodeGen/object-size-flex-array.c

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index ee1012efc086d..d921ea5d5da99 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -1143,7 +1143,7 @@ def fallow_unsupported : Flag<["-"], "fallow-unsupported">, Group<f_Group>;
 def fapple_kext : Flag<["-"], "fapple-kext">, Group<f_Group>, Flags<[CC1Option]>,
   HelpText<"Use Apple's kernel extensions ABI">,
   MarshallingInfoFlag<LangOpts<"AppleKext">>;
-def fstrict_flex_arrays_EQ : Joined<["-"], "fstrict-flex-arrays=">,Group<f_Group>,
+def fstrict_flex_arrays_EQ : Joined<["-"], "fstrict-flex-arrays=">, Group<f_Group>,
   MetaVarName<"<n>">, Values<"0,1,2">,
   LangOpts<"StrictFlexArrays">,
   Flags<[CC1Option]>,

diff  --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index e26822eaa601e..324eb56167b56 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -906,10 +906,8 @@ static bool isFlexibleArrayMemberExpr(const Expr *E,
     if (const auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl())) {
       // FIXME: Sema doesn't treat a T[1] union member as a flexible array
       // member, only a T[0] or T[] member gets that treatment.
-      // Under StrictFlexArraysLevel, obey c99+ that disallows FAM in union, see
-      // C11 6.7.2.1 ยง18
       if (FD->getParent()->isUnion())
-        return StrictFlexArraysLevel < 2;
+        return true;
       RecordDecl::field_iterator FI(
           DeclContext::decl_iterator(const_cast<FieldDecl *>(FD)));
       return ++FI == FD->getParent()->field_end();

diff  --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 03b0c72fac9b6..897ab701493c2 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -15888,16 +15888,10 @@ static bool IsTailPaddedMemberArray(Sema &S, const llvm::APInt &Size,
   if (!ND)
     return false;
 
-  if (StrictFlexArraysLevel >= 2 && Size != 0)
-    return false;
-
-  if (StrictFlexArraysLevel == 1 && Size.uge(2))
-    return false;
-
   // FIXME: While the default -fstrict-flex-arrays=0 permits Size>1 trailing
   // arrays to be treated as flexible-array-members, we still emit diagnostics
   // as if they are not. Pending further discussion...
-  if (StrictFlexArraysLevel == 0 && Size != 1)
+  if (StrictFlexArraysLevel >= 2 || Size.uge(2))
     return false;
 
   const FieldDecl *FD = dyn_cast<FieldDecl>(ND);
@@ -16065,8 +16059,8 @@ void Sema::CheckArrayAccess(const Expr *BaseExpr, const Expr *IndexExpr,
     if (BaseType->isIncompleteType())
       return;
 
-    // FIXME: this check should belong to the IsTailPaddedMemberArray call
-    // below.
+    // FIXME: this check should be used to set IsUnboundedArray from the
+    // beginning.
     llvm::APInt size = ArrayTy->getSize();
     if (!size.isStrictlyPositive())
       return;

diff  --git a/clang/test/CodeGen/bounds-checking-fam.c b/clang/test/CodeGen/bounds-checking-fam.c
index 8a96c261992a5..1b4f183bee12b 100644
--- a/clang/test/CodeGen/bounds-checking-fam.c
+++ b/clang/test/CodeGen/bounds-checking-fam.c
@@ -35,6 +35,51 @@ int test_two(struct Two *p, int i) {
   return p->a[i] + (p->a)[i];
 }
 
+union uZero {
+  int a[0];
+};
+union uOne {
+  int a[1];
+};
+union uTwo {
+  int a[2];
+};
+union uThree {
+  int a[3];
+};
+
+// CHECK-LABEL: define {{.*}} @{{.*}}test_uzero{{.*}}(
+int test_uzero(union uZero *p, int i) {
+  // CHECK-STRICT-0-NOT: @__ubsan
+  // CHECK-STRICT-1-NOT: @__ubsan
+  // CHECK-STRICT-2-NOT: @__ubsan
+  return p->a[i] + (p->a)[i];
+}
+
+// CHECK-LABEL: define {{.*}} @{{.*}}test_uone{{.*}}(
+int test_uone(union uOne *p, int i) {
+  // CHECK-STRICT-0-NOT: @__ubsan
+  // CHECK-STRICT-1-NOT: @__ubsan
+  // CHECK-STRICT-2: @__ubsan
+  return p->a[i] + (p->a)[i];
+}
+
+// CHECK-LABEL: define {{.*}} @{{.*}}test_utwo{{.*}}(
+int test_utwo(union uTwo *p, int i) {
+  // CHECK-STRICT-0: @__ubsan
+  // CHECK-STRICT-1: @__ubsan
+  // CHECK-STRICT-2: @__ubsan
+  return p->a[i] + (p->a)[i];
+}
+
+// CHECK-LABEL: define {{.*}} @{{.*}}test_uthree{{.*}}(
+int test_uthree(union uThree *p, int i) {
+  // CHECK-STRICT-0: @__ubsan
+  // CHECK-STRICT-1: @__ubsan
+  // CHECK-STRICT-2: @__ubsan
+  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(

diff  --git a/clang/test/CodeGen/object-size-flex-array.c b/clang/test/CodeGen/object-size-flex-array.c
index f97b6eb36452f..83c0bd634605d 100644
--- a/clang/test/CodeGen/object-size-flex-array.c
+++ b/clang/test/CodeGen/object-size-flex-array.c
@@ -24,7 +24,7 @@ typedef struct {
   double c[2];
 } foo2_t;
 
-// CHECK-LABEL: @bar
+// CHECK-LABEL: @bar(
 unsigned bar(foo_t *f) {
   // CHECK-STRICT-0: ret i32 %
   // CHECK-STRICT-1: ret i32 %
@@ -32,7 +32,7 @@ unsigned bar(foo_t *f) {
   return OBJECT_SIZE_BUILTIN(f->c, 1);
 }
 
-// CHECK-LABEL: @bar0
+// CHECK-LABEL: @bar0(
 unsigned bar0(foo0_t *f) {
   // CHECK-STRICT-0: ret i32 %
   // CHECK-STRICT-1: ret i32 %
@@ -40,7 +40,7 @@ unsigned bar0(foo0_t *f) {
   return OBJECT_SIZE_BUILTIN(f->c, 1);
 }
 
-// CHECK-LABEL: @bar1
+// CHECK-LABEL: @bar1(
 unsigned bar1(foo1_t *f) {
   // CHECK-STRICT-0: ret i32 %
   // CHECK-STRICT-1: ret i32 %
@@ -48,7 +48,7 @@ unsigned bar1(foo1_t *f) {
   return OBJECT_SIZE_BUILTIN(f->c, 1);
 }
 
-// CHECK-LABEL: @bar2
+// CHECK-LABEL: @bar2(
 unsigned bar2(foo2_t *f) {
   // CHECK-STRICT-0: ret i32 %
   // CHECK-STRICT-1: ret i32 16
@@ -73,7 +73,7 @@ typedef struct {
   float f;
 } foofoo2_t;
 
-// CHECK-LABEL: @babar0
+// CHECK-LABEL: @babar0(
 unsigned babar0(foofoo0_t *f) {
   // CHECK-STRICT-0: ret i32 0
   // CHECK-STRICT-1: ret i32 0
@@ -81,7 +81,7 @@ unsigned babar0(foofoo0_t *f) {
   return OBJECT_SIZE_BUILTIN(f->c, 1);
 }
 
-// CHECK-LABEL: @babar1
+// CHECK-LABEL: @babar1(
 unsigned babar1(foofoo1_t *f) {
   // CHECK-STRICT-0: ret i32 8
   // CHECK-STRICT-1: ret i32 8
@@ -89,7 +89,7 @@ unsigned babar1(foofoo1_t *f) {
   return OBJECT_SIZE_BUILTIN(f->c, 1);
 }
 
-// CHECK-LABEL: @babar2
+// CHECK-LABEL: @babar2(
 unsigned babar2(foofoo2_t *f) {
   // CHECK-STRICT-0: ret i32 16
   // CHECK-STRICT-1: ret i32 16


        


More information about the cfe-commits mailing list