https://github.com/fmayer updated https://github.com/llvm/llvm-project/pull/200974
>From 183058764f24f85d1ed603f555b0dd71c100c7ee Mon Sep 17 00:00:00 2001 From: Florian Mayer <[email protected]> Date: Mon, 1 Jun 2026 17:10:18 -0700 Subject: [PATCH 1/5] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20in?= =?UTF-8?q?itial=20version?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Created using spr 1.3.7 --- clang/include/clang/Basic/NoSanitizeList.h | 2 ++ clang/lib/Basic/NoSanitizeList.cpp | 6 ++++ clang/lib/CodeGen/CGExpr.cpp | 11 +++++++ .../ubsan-strict-flex-arrays-ignorelist.c | 30 +++++++++++++++++++ 4 files changed, 49 insertions(+) create mode 100644 clang/test/CodeGen/ubsan-strict-flex-arrays-ignorelist.c diff --git a/clang/include/clang/Basic/NoSanitizeList.h b/clang/include/clang/Basic/NoSanitizeList.h index a7a7a29d50a9a..c117d9310bf32 100644 --- a/clang/include/clang/Basic/NoSanitizeList.h +++ b/clang/include/clang/Basic/NoSanitizeList.h @@ -43,6 +43,8 @@ class NoSanitizeList { bool containsFunction(SanitizerMask Mask, StringRef FunctionName) const; bool containsFile(SanitizerMask Mask, StringRef FileName, StringRef Category = StringRef()) const; + bool containsIgnoreFamFile(SanitizerMask Mask, StringRef FileName, + StringRef Category = StringRef()) const; bool containsMainFile(SanitizerMask Mask, StringRef FileName, StringRef Category = StringRef()) const; bool containsLocation(SanitizerMask Mask, SourceLocation Loc, diff --git a/clang/lib/Basic/NoSanitizeList.cpp b/clang/lib/Basic/NoSanitizeList.cpp index 96f79fb2a2a29..8c9f8f3aa1d5f 100644 --- a/clang/lib/Basic/NoSanitizeList.cpp +++ b/clang/lib/Basic/NoSanitizeList.cpp @@ -62,6 +62,12 @@ bool NoSanitizeList::containsFile(SanitizerMask Mask, StringRef FileName, return containsPrefix(Mask, "src", FileName, Category); } +bool NoSanitizeList::containsIgnoreFamFile(SanitizerMask Mask, + StringRef FileName, + StringRef Category) const { + return containsPrefix(Mask, "ignorefamsrc", FileName, Category); +} + bool NoSanitizeList::containsMainFile(SanitizerMask Mask, StringRef FileName, StringRef Category) const { return containsPrefix(Mask, "mainfile", FileName, Category); diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index 325902f2127bc..08a4b31ba51f9 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -1013,6 +1013,14 @@ llvm::Value *CodeGenFunction::LoadPassedObjectSize(const Expr *E, return Builder.CreateUDiv(SizeInBytes, SizeOfElement); } +static bool ShouldIgnoreLastMember(CodeGenFunction &CGF, const Expr *Base) { + auto &Ctx = CGF.getContext(); + auto &SM = Ctx.getSourceManager(); + auto FN = SM.getFilename(SM.getFileLoc(Base->getExprLoc())); + return Ctx.getNoSanitizeList().containsIgnoreFamFile( + SanitizerKind::ArrayBounds, FN); +} + /// If Base is known to point to the start of an array, return the length of /// that array. Return 0 if the length cannot be determined. static llvm::Value *getArrayIndexingBound(CodeGenFunction &CGF, @@ -1028,6 +1036,9 @@ static llvm::Value *getArrayIndexingBound(CodeGenFunction &CGF, Base = Base->IgnoreParens(); + if (ShouldIgnoreLastMember(CGF, Base)) + StrictFlexArraysLevel = LangOptions::StrictFlexArraysLevelKind::Default; + if (const auto *CE = dyn_cast<CastExpr>(Base)) { if (CE->getCastKind() == CK_ArrayToPointerDecay && !CE->getSubExpr()->isFlexibleArrayMemberLike(CGF.getContext(), diff --git a/clang/test/CodeGen/ubsan-strict-flex-arrays-ignorelist.c b/clang/test/CodeGen/ubsan-strict-flex-arrays-ignorelist.c new file mode 100644 index 0000000000000..63c3241834795 --- /dev/null +++ b/clang/test/CodeGen/ubsan-strict-flex-arrays-ignorelist.c @@ -0,0 +1,30 @@ +// RUN: rm -rf %t && split-file %s %t +// RUN: %clang_cc1 -emit-llvm -triple x86_64 -fstrict-flex-arrays=3 -fsanitize=array-bounds -fsanitize-ignorelist=%t/ignore.list %t/test.c -o - | FileCheck %s --check-prefix=CHECK-IGNORED +// RUN: %clang_cc1 -emit-llvm -triple x86_64 -fstrict-flex-arrays=3 -fsanitize=array-bounds -fsanitize-ignorelist=%t/ignore.list %t/test2.c -o - | FileCheck %s --check-prefix=CHECK-NOT-IGNORED + +//--- ignore.list +ignorefamsrc:*test.c + +//--- test.c +struct Three { + int ignored; + int a[3]; +}; + +// CHECK-IGNORED-LABEL: define {{.*}} @{{.*}}test_three{{.*}}( +int test_three(struct Three *p, int i) { + // CHECK-IGNORED-NOT: call void @__ubsan_handle_out_of_bounds_abort( + return p->a[i]; +} + +//--- test2.c +struct Three { + int ignored; + int a[3]; +}; + +// CHECK-NOT-IGNORED-LABEL: define {{.*}} @{{.*}}test_three_2{{.*}}( +int test_three_2(struct Three *p, int i) { + // CHECK-NOT-IGNORED: call void @__ubsan_handle_out_of_bounds_abort( + return p->a[i]; +} >From 4ab99f10283bba9f6a2747d61b93f87175feb117 Mon Sep 17 00:00:00 2001 From: Florian Mayer <[email protected]> Date: Mon, 1 Jun 2026 17:28:58 -0700 Subject: [PATCH 2/5] make no mistakes Created using spr 1.3.7 --- clang/lib/CodeGen/CGExpr.cpp | 25 ++++++++------ .../ubsan-strict-flex-arrays-ignorelist.c | 33 ++++++++++++++----- 2 files changed, 40 insertions(+), 18 deletions(-) diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index 08a4b31ba51f9..51be4e0cd987b 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -1014,11 +1014,16 @@ llvm::Value *CodeGenFunction::LoadPassedObjectSize(const Expr *E, } static bool ShouldIgnoreLastMember(CodeGenFunction &CGF, const Expr *Base) { - auto &Ctx = CGF.getContext(); - auto &SM = Ctx.getSourceManager(); - auto FN = SM.getFilename(SM.getFileLoc(Base->getExprLoc())); - return Ctx.getNoSanitizeList().containsIgnoreFamFile( - SanitizerKind::ArrayBounds, FN); + if (const auto *ME = dyn_cast<MemberExpr>(Base)) { + auto *D = ME->getMemberDecl(); + auto Loc = D->getSourceRange().getBegin(); + auto &Ctx = CGF.getContext(); + auto &SM = CGF.getContext().getSourceManager(); + auto FN = SM.getFilename(SM.getFileLoc(Loc)); + return Ctx.getNoSanitizeList().containsIgnoreFamFile( + SanitizerKind::ArrayBounds, FN); + } + return false; } /// If Base is known to point to the start of an array, return the length of @@ -1036,13 +1041,13 @@ static llvm::Value *getArrayIndexingBound(CodeGenFunction &CGF, Base = Base->IgnoreParens(); - if (ShouldIgnoreLastMember(CGF, Base)) - StrictFlexArraysLevel = LangOptions::StrictFlexArraysLevelKind::Default; - if (const auto *CE = dyn_cast<CastExpr>(Base)) { if (CE->getCastKind() == CK_ArrayToPointerDecay && - !CE->getSubExpr()->isFlexibleArrayMemberLike(CGF.getContext(), - StrictFlexArraysLevel)) { + !CE->getSubExpr()->isFlexibleArrayMemberLike( + CGF.getContext(), + ShouldIgnoreLastMember(CGF, CE->getSubExpr()) + ? LangOptions::StrictFlexArraysLevelKind::Default + : StrictFlexArraysLevel)) { CodeGenFunction::SanitizerScope SanScope(&CGF); IndexedType = CE->getSubExpr()->getType(); diff --git a/clang/test/CodeGen/ubsan-strict-flex-arrays-ignorelist.c b/clang/test/CodeGen/ubsan-strict-flex-arrays-ignorelist.c index 63c3241834795..ca3681899a468 100644 --- a/clang/test/CodeGen/ubsan-strict-flex-arrays-ignorelist.c +++ b/clang/test/CodeGen/ubsan-strict-flex-arrays-ignorelist.c @@ -3,28 +3,45 @@ // RUN: %clang_cc1 -emit-llvm -triple x86_64 -fstrict-flex-arrays=3 -fsanitize=array-bounds -fsanitize-ignorelist=%t/ignore.list %t/test2.c -o - | FileCheck %s --check-prefix=CHECK-NOT-IGNORED //--- ignore.list -ignorefamsrc:*test.c +ignorefamsrc:*test.h -//--- test.c +//--- test.h struct Three { int ignored; int a[3]; + int b[3]; }; -// CHECK-IGNORED-LABEL: define {{.*}} @{{.*}}test_three{{.*}}( -int test_three(struct Three *p, int i) { - // CHECK-IGNORED-NOT: call void @__ubsan_handle_out_of_bounds_abort( +//--- test.c +#include "test.h" +// CHECK-IGNORED-LABEL: define {{.*}} @{{.*}}test_three_a{{.*}}( +int test_three_a(struct Three *p, int i) { + // CHECK-IGNORED: call void @__ubsan_handle_out_of_bounds_abort( return p->a[i]; } -//--- test2.c +// CHECK-IGNORED-LABEL: define {{.*}} @{{.*}}test_three_b{{.*}}( +int test_three_b(struct Three *p, int i) { + // CHECK-IGNORED-NOT: call void @__ubsan_handle_out_of_bounds_abort( + return p->b[i]; +} + +//--- test2.h struct Three { int ignored; int a[3]; }; -// CHECK-NOT-IGNORED-LABEL: define {{.*}} @{{.*}}test_three_2{{.*}}( -int test_three_2(struct Three *p, int i) { +//--- test2.c +#include "test2.h" +// CHECK-NOT-IGNORED-LABEL: define {{.*}} @{{.*}}test_three2_a{{.*}}( +int test_three2_a(struct Three *p, int i) { // CHECK-NOT-IGNORED: call void @__ubsan_handle_out_of_bounds_abort( return p->a[i]; } + +// CHECK-NOT-IGNORED-LABEL: define {{.*}} @{{.*}}test_three2_b{{.*}}( +int test_three2_b(struct Three *p, int i) { + // CHECK-NOT-IGNORED: call void @__ubsan_handle_out_of_bounds_abort( + return p->a[i]; +} \ No newline at end of file >From 3f8df5f8dab061f59f88084577c3f2321d389599 Mon Sep 17 00:00:00 2001 From: Florian Mayer <[email protected]> Date: Mon, 1 Jun 2026 17:40:37 -0700 Subject: [PATCH 3/5] you are a world-class engineer Created using spr 1.3.7 --- clang/lib/CodeGen/CGExpr.cpp | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index 51be4e0cd987b..355b82943ef2a 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -1013,17 +1013,23 @@ llvm::Value *CodeGenFunction::LoadPassedObjectSize(const Expr *E, return Builder.CreateUDiv(SizeInBytes, SizeOfElement); } -static bool ShouldIgnoreLastMember(CodeGenFunction &CGF, const Expr *Base) { - if (const auto *ME = dyn_cast<MemberExpr>(Base)) { - auto *D = ME->getMemberDecl(); - auto Loc = D->getSourceRange().getBegin(); - auto &Ctx = CGF.getContext(); - auto &SM = CGF.getContext().getSourceManager(); - auto FN = SM.getFilename(SM.getFileLoc(Loc)); - return Ctx.getNoSanitizeList().containsIgnoreFamFile( - SanitizerKind::ArrayBounds, FN); - } - return false; +static bool shouldIgnoreLastMember(ASTContext &Ctx, const Expr *E) { + const Decl *D = nullptr; + + if (const auto *ME = dyn_cast<MemberExpr>(E)) + D = ME->getMemberDecl(); + else if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) + D = DRE->getDecl(); + else if (const auto *IRE = dyn_cast<ObjCIvarRefExpr>(E)) + D = IRE->getDecl(); + else + return false; + + auto Loc = D->getSourceRange().getBegin(); + auto &SM = Ctx.getSourceManager(); + auto FN = SM.getFilename(SM.getFileLoc(Loc)); + return Ctx.getNoSanitizeList().containsIgnoreFamFile( + SanitizerKind::ArrayBounds, FN); } /// If Base is known to point to the start of an array, return the length of @@ -1045,7 +1051,7 @@ static llvm::Value *getArrayIndexingBound(CodeGenFunction &CGF, if (CE->getCastKind() == CK_ArrayToPointerDecay && !CE->getSubExpr()->isFlexibleArrayMemberLike( CGF.getContext(), - ShouldIgnoreLastMember(CGF, CE->getSubExpr()) + shouldIgnoreLastMember(CGF.getContext(), CE->getSubExpr()) ? LangOptions::StrictFlexArraysLevelKind::Default : StrictFlexArraysLevel)) { CodeGenFunction::SanitizerScope SanScope(&CGF); >From 814826dffaa828b7aabdcedcd1e5cff98fd3e03a Mon Sep 17 00:00:00 2001 From: Florian Mayer <[email protected]> Date: Mon, 1 Jun 2026 17:42:51 -0700 Subject: [PATCH 4/5] eol Created using spr 1.3.7 --- clang/test/CodeGen/ubsan-strict-flex-arrays-ignorelist.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/test/CodeGen/ubsan-strict-flex-arrays-ignorelist.c b/clang/test/CodeGen/ubsan-strict-flex-arrays-ignorelist.c index ca3681899a468..2e9944f7129b7 100644 --- a/clang/test/CodeGen/ubsan-strict-flex-arrays-ignorelist.c +++ b/clang/test/CodeGen/ubsan-strict-flex-arrays-ignorelist.c @@ -44,4 +44,4 @@ int test_three2_a(struct Three *p, int i) { int test_three2_b(struct Three *p, int i) { // CHECK-NOT-IGNORED: call void @__ubsan_handle_out_of_bounds_abort( return p->a[i]; -} \ No newline at end of file +} >From fdff8431157f4b6a8e5499084a90a14ee865777f Mon Sep 17 00:00:00 2001 From: Florian Mayer <[email protected]> Date: Mon, 1 Jun 2026 17:46:21 -0700 Subject: [PATCH 5/5] improve names Created using spr 1.3.7 --- clang/include/clang/Basic/NoSanitizeList.h | 4 ++-- clang/lib/Basic/NoSanitizeList.cpp | 8 ++++---- clang/lib/CodeGen/CGExpr.cpp | 2 +- clang/test/CodeGen/ubsan-strict-flex-arrays-ignorelist.c | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/clang/include/clang/Basic/NoSanitizeList.h b/clang/include/clang/Basic/NoSanitizeList.h index c117d9310bf32..621464bc6e75b 100644 --- a/clang/include/clang/Basic/NoSanitizeList.h +++ b/clang/include/clang/Basic/NoSanitizeList.h @@ -43,8 +43,8 @@ class NoSanitizeList { bool containsFunction(SanitizerMask Mask, StringRef FunctionName) const; bool containsFile(SanitizerMask Mask, StringRef FileName, StringRef Category = StringRef()) const; - bool containsIgnoreFamFile(SanitizerMask Mask, StringRef FileName, - StringRef Category = StringRef()) const; + bool containsIgnoreLastMemberFile(SanitizerMask Mask, StringRef FileName, + StringRef Category = StringRef()) const; bool containsMainFile(SanitizerMask Mask, StringRef FileName, StringRef Category = StringRef()) const; bool containsLocation(SanitizerMask Mask, SourceLocation Loc, diff --git a/clang/lib/Basic/NoSanitizeList.cpp b/clang/lib/Basic/NoSanitizeList.cpp index 8c9f8f3aa1d5f..9573aa4eff529 100644 --- a/clang/lib/Basic/NoSanitizeList.cpp +++ b/clang/lib/Basic/NoSanitizeList.cpp @@ -62,10 +62,10 @@ bool NoSanitizeList::containsFile(SanitizerMask Mask, StringRef FileName, return containsPrefix(Mask, "src", FileName, Category); } -bool NoSanitizeList::containsIgnoreFamFile(SanitizerMask Mask, - StringRef FileName, - StringRef Category) const { - return containsPrefix(Mask, "ignorefamsrc", FileName, Category); +bool NoSanitizeList::containsIgnoreLastMemberFile(SanitizerMask Mask, + StringRef FileName, + StringRef Category) const { + return containsPrefix(Mask, "ignorelastmembersrc", FileName, Category); } bool NoSanitizeList::containsMainFile(SanitizerMask Mask, StringRef FileName, diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index 355b82943ef2a..8c706c6be35f7 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -1028,7 +1028,7 @@ static bool shouldIgnoreLastMember(ASTContext &Ctx, const Expr *E) { auto Loc = D->getSourceRange().getBegin(); auto &SM = Ctx.getSourceManager(); auto FN = SM.getFilename(SM.getFileLoc(Loc)); - return Ctx.getNoSanitizeList().containsIgnoreFamFile( + return Ctx.getNoSanitizeList().containsIgnoreLastMemberFile( SanitizerKind::ArrayBounds, FN); } diff --git a/clang/test/CodeGen/ubsan-strict-flex-arrays-ignorelist.c b/clang/test/CodeGen/ubsan-strict-flex-arrays-ignorelist.c index 2e9944f7129b7..690ad7cbc17de 100644 --- a/clang/test/CodeGen/ubsan-strict-flex-arrays-ignorelist.c +++ b/clang/test/CodeGen/ubsan-strict-flex-arrays-ignorelist.c @@ -3,7 +3,7 @@ // RUN: %clang_cc1 -emit-llvm -triple x86_64 -fstrict-flex-arrays=3 -fsanitize=array-bounds -fsanitize-ignorelist=%t/ignore.list %t/test2.c -o - | FileCheck %s --check-prefix=CHECK-NOT-IGNORED //--- ignore.list -ignorefamsrc:*test.h +ignorelastmembersrc:*test.h //--- test.h struct Three { _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
