[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