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 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits