https://github.com/vitalybuka updated https://github.com/llvm/llvm-project/pull/141540
>From e7540c31c69df827d646e88b271a355c587bd9da Mon Sep 17 00:00:00 2001 From: Qinkun Bao <qin...@google.com> Date: Tue, 27 May 2025 02:36:29 +0000 Subject: [PATCH 1/4] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20ch?= =?UTF-8?q?anges=20to=20main=20this=20commit=20is=20based=20on?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Created using spr 1.3.6 [skip ci] --- clang/docs/ReleaseNotes.rst | 1 + clang/docs/SanitizerSpecialCaseList.rst | 26 +++++++++++--- .../clang/Basic/SanitizerSpecialCaseList.h | 7 +++- clang/lib/Basic/NoSanitizeList.cpp | 10 +++++- clang/lib/Basic/SanitizerSpecialCaseList.cpp | 21 ++++++++--- .../ubsan-src-ignorelist-category.test | 36 ++++++++++++++++--- llvm/lib/Support/SpecialCaseList.cpp | 18 +++++----- .../unittests/Support/SpecialCaseListTest.cpp | 23 ++++++++++++ 8 files changed, 116 insertions(+), 26 deletions(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index b93fa33acc2a0..80a5b7072677d 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -1009,6 +1009,7 @@ Sanitizers ---------- - ``-fsanitize=vptr`` is no longer a part of ``-fsanitize=undefined``. +- Sanitizer ignorelists now support the syntax ``src:*=sanitize``. Python Binding Changes ---------------------- diff --git a/clang/docs/SanitizerSpecialCaseList.rst b/clang/docs/SanitizerSpecialCaseList.rst index 5c88c2976e861..692af8df0359b 100644 --- a/clang/docs/SanitizerSpecialCaseList.rst +++ b/clang/docs/SanitizerSpecialCaseList.rst @@ -58,7 +58,7 @@ Usage with UndefinedBehaviorSanitizer ability to adjust instrumentation based on type. By default, supported sanitizers will have their instrumentation disabled for -types specified within an ignorelist. +entries specified within an ignorelist. .. code-block:: bash @@ -77,10 +77,9 @@ For example, supplying the above ``ignorelist.txt`` to ``-fsanitize-ignorelist=ignorelist.txt`` disables overflow sanitizer instrumentation for arithmetic operations containing values of type ``int``. -The ``=sanitize`` category is also supported. Any types assigned to the -``sanitize`` category will have their sanitizer instrumentation remain. If the -same type appears within or across ignorelists with different categories the -``sanitize`` category takes precedence -- regardless of order. +The ``=sanitize`` category is also supported. Any ``=sanitize`` category +entries enable sanitizer instrumentation, even if it was ignored by entries +before. With this, one may disable instrumentation for some or all types and specifically allow instrumentation for one or many types -- including types @@ -103,6 +102,23 @@ supported sanitizers. char c = toobig; // also not instrumented } +If multiple entries match the source, than the latest entry takes the +precedence. + +.. code-block:: bash + + $ cat ignorelist1.txt + # test.cc will be instrumented. + src:* + src:*/mylib/*=sanitize + src:*/mylib/test.cc + + $ cat ignorelist2.txt + # test.cc will not be instrumented. + src:* + src:*/mylib/test.cc + src:*/mylib/*=sanitize + Format ====== diff --git a/clang/include/clang/Basic/SanitizerSpecialCaseList.h b/clang/include/clang/Basic/SanitizerSpecialCaseList.h index d024b7dfc2e85..25d518e7128cf 100644 --- a/clang/include/clang/Basic/SanitizerSpecialCaseList.h +++ b/clang/include/clang/Basic/SanitizerSpecialCaseList.h @@ -43,13 +43,18 @@ class SanitizerSpecialCaseList : public llvm::SpecialCaseList { bool inSection(SanitizerMask Mask, StringRef Prefix, StringRef Query, StringRef Category = StringRef()) const; + // Query ignorelisted entries if any bit in Mask matches the entry's section. + // Return 0 if not found. If found, return the line number (starts with 1). + unsigned inSectionBlame(SanitizerMask Mask, StringRef Prefix, StringRef Query, + StringRef Category = StringRef()) const; + protected: // Initialize SanitizerSections. void createSanitizerSections(); struct SanitizerSection { SanitizerSection(SanitizerMask SM, SectionEntries &E) - : Mask(SM), Entries(E){}; + : Mask(SM), Entries(E) {}; SanitizerMask Mask; SectionEntries &Entries; diff --git a/clang/lib/Basic/NoSanitizeList.cpp b/clang/lib/Basic/NoSanitizeList.cpp index e7e63c1f419e6..4feef5c6ea052 100644 --- a/clang/lib/Basic/NoSanitizeList.cpp +++ b/clang/lib/Basic/NoSanitizeList.cpp @@ -44,7 +44,15 @@ bool NoSanitizeList::containsFunction(SanitizerMask Mask, bool NoSanitizeList::containsFile(SanitizerMask Mask, StringRef FileName, StringRef Category) const { - return SSCL->inSection(Mask, "src", FileName, Category); + unsigned NoSanLine = SSCL->inSectionBlame(Mask, "src", FileName, Category); + if (NoSanLine == 0) + return false; + unsigned SanLine = SSCL->inSectionBlame(Mask, "src", FileName, "sanitize"); + // If we have two cases such as `src:a.cpp=sanitize` and `src:a.cpp`, the + // current entry override the previous entry. + if (SanLine > 0) + return NoSanLine > SanLine; + return true; } bool NoSanitizeList::containsMainFile(SanitizerMask Mask, StringRef FileName, diff --git a/clang/lib/Basic/SanitizerSpecialCaseList.cpp b/clang/lib/Basic/SanitizerSpecialCaseList.cpp index 2dbf04c6ede97..4508d705eb43a 100644 --- a/clang/lib/Basic/SanitizerSpecialCaseList.cpp +++ b/clang/lib/Basic/SanitizerSpecialCaseList.cpp @@ -56,10 +56,21 @@ void SanitizerSpecialCaseList::createSanitizerSections() { bool SanitizerSpecialCaseList::inSection(SanitizerMask Mask, StringRef Prefix, StringRef Query, StringRef Category) const { - for (auto &S : SanitizerSections) - if ((S.Mask & Mask) && - SpecialCaseList::inSectionBlame(S.Entries, Prefix, Query, Category)) - return true; + return inSectionBlame(Mask, Prefix, Query, Category); +} - return false; +unsigned SanitizerSpecialCaseList::inSectionBlame(SanitizerMask Mask, + StringRef Prefix, + StringRef Query, + StringRef Category) const { + for (auto it = SanitizerSections.crbegin(); it != SanitizerSections.crend(); + ++it) { + if (it->Mask & Mask) { + unsigned lineNum = + SpecialCaseList::inSectionBlame(it->Entries, Prefix, Query, Category); + if (lineNum > 0) + return lineNum; + } + } + return 0; } diff --git a/clang/test/CodeGen/ubsan-src-ignorelist-category.test b/clang/test/CodeGen/ubsan-src-ignorelist-category.test index 2f196fb126fe7..55967ec77c836 100644 --- a/clang/test/CodeGen/ubsan-src-ignorelist-category.test +++ b/clang/test/CodeGen/ubsan-src-ignorelist-category.test @@ -3,14 +3,15 @@ // RUN: %clang_cc1 -triple x86_64-linux-gnu -fsanitize=signed-integer-overflow -fsanitize-ignorelist=%t/src.ignorelist -emit-llvm %t/test2.c -o - | FileCheck %s --check-prefixes=CHECK2 -// RUN: %clang_cc1 -triple x86_64-linux-gnu -fsanitize=signed-integer-overflow -fsanitize-ignorelist=%t/src.ignorelist -emit-llvm %t/test1.c -o - | FileCheck %s --check-prefixes=CHECK1,IGNORE +// RUN: %clang_cc1 -triple x86_64-linux-gnu -fsanitize=signed-integer-overflow -fsanitize-ignorelist=%t/src.ignorelist -emit-llvm %t/test1.c -o - | FileCheck %s --check-prefixes=CHECK1,SANITIZE // RUN: %clang_cc1 -triple x86_64-linux-gnu -fsanitize=signed-integer-overflow -fsanitize-ignorelist=%t/src.ignorelist.contradict1 -emit-llvm %t/test1.c -o - | FileCheck %s --check-prefixes=CHECK1,IGNORE -// RUN: %clang_cc1 -triple x86_64-linux-gnu -fsanitize=signed-integer-overflow -fsanitize-ignorelist=%t/src.ignorelist.contradict2 -emit-llvm %t/test1.c -o - | FileCheck %s --check-prefixes=CHECK1,IGNORE +// RUN: %clang_cc1 -triple x86_64-linux-gnu -fsanitize=signed-integer-overflow -fsanitize-ignorelist=%t/src.ignorelist.contradict2 -emit-llvm %t/test1.c -o - | FileCheck %s --check-prefixes=CHECK1,SANITIZE // RUN: %clang_cc1 -triple x86_64-linux-gnu -fsanitize=signed-integer-overflow -fsanitize-ignorelist=%t/src.ignorelist.contradict3 -emit-llvm %t/test1.c -o - | FileCheck %s --check-prefixes=CHECK1,IGNORE -// RUN: %clang_cc1 -triple x86_64-linux-gnu -fsanitize=signed-integer-overflow -fsanitize-ignorelist=%t/src.ignorelist.contradict4 -emit-llvm %t/test1.c -o - | FileCheck %s --check-prefixes=CHECK1,IGNORE +// RUN: %clang_cc1 -triple x86_64-linux-gnu -fsanitize=signed-integer-overflow -fsanitize-ignorelist=%t/src.ignorelist.contradict4 -emit-llvm %t/test1.c -o - | FileCheck %s --check-prefixes=CHECK1,SANITIZE // RUN: %clang_cc1 -triple x86_64-linux-gnu -fsanitize=signed-integer-overflow -fsanitize-ignorelist=%t/src.ignorelist.contradict5 -emit-llvm %t/test1.c -o - | FileCheck %s --check-prefixes=CHECK1,IGNORE -// RUN: %clang_cc1 -triple x86_64-linux-gnu -fsanitize=signed-integer-overflow -fsanitize-ignorelist=%t/src.ignorelist.contradict6 -emit-llvm %t/test1.c -o - | FileCheck %s --check-prefixes=CHECK1,IGNORE - +// RUN: %clang_cc1 -triple x86_64-linux-gnu -fsanitize=signed-integer-overflow -fsanitize-ignorelist=%t/src.ignorelist.contradict6 -emit-llvm %t/test1.c -o - | FileCheck %s --check-prefixes=CHECK1,SANITIZE +// RUN: %clang_cc1 -triple x86_64-linux-gnu -fsanitize=signed-integer-overflow -fsanitize-ignorelist=%t/src.ignorelist.contradict7 -emit-llvm %t/test1.c -o - | FileCheck %s --check-prefixes=CHECK1,IGNORE +// RUN: %clang_cc1 -triple x86_64-linux-gnu -fsanitize=signed-integer-overflow -fsanitize-ignorelist=%t/src.ignorelist.contradict8 -emit-llvm %t/test1.c -o - | FileCheck %s --check-prefixes=CHECK1,SANITIZE // Verify ubsan only emits checks for files in the allowlist @@ -52,6 +53,31 @@ src:*/tes*1.c=sanitize src:*/te*t1.c src:*/t*st1.c=sanitize +//--- src.ignorelist.contradict7 +[{unsigned-integer-overflow,signed-integer-overflow}] +src:* +src:*/tes*1.c=sanitize +src:*/te*t1.c +src:*/t*st1.c=sanitize +[{unsigned-integer-overflow,signed-integer-overflow}] +src:* +src:*/te*t1.c +src:*/tes*1.c=sanitize +src:*/test1.c + +//--- src.ignorelist.contradict8 +[{unsigned-integer-overflow,signed-integer-overflow}] +src:* +src:*/te*t1.c +src:*/tes*1.c=sanitize +src:*/test1.c +[{unsigned-integer-overflow,signed-integer-overflow}] +src:* +src:*/tes*1.c=sanitize +src:*/te*t1.c +src:*/t*st1.c=sanitize + + //--- test1.c // CHECK1-LABEL: define dso_local i32 @add int add(int a, int b) { diff --git a/llvm/lib/Support/SpecialCaseList.cpp b/llvm/lib/Support/SpecialCaseList.cpp index 47ff3e24706a4..56327b56282c2 100644 --- a/llvm/lib/Support/SpecialCaseList.cpp +++ b/llvm/lib/Support/SpecialCaseList.cpp @@ -66,12 +66,12 @@ Error SpecialCaseList::Matcher::insert(StringRef Pattern, unsigned LineNumber, } unsigned SpecialCaseList::Matcher::match(StringRef Query) const { - for (const auto &Glob : Globs) - if (Glob->Pattern.match(Query)) - return Glob->LineNo; - for (const auto &[Regex, LineNumber] : RegExes) - if (Regex->match(Query)) - return LineNumber; + for (auto it = Globs.crbegin(); it != Globs.crend(); ++it) + if ((*it)->Pattern.match(Query)) + return (*it)->LineNo; + for (auto it = RegExes.crbegin(); it != RegExes.crend(); ++it) + if (it->first->match(Query)) + return it->second; return 0; } @@ -213,9 +213,9 @@ bool SpecialCaseList::inSection(StringRef Section, StringRef Prefix, unsigned SpecialCaseList::inSectionBlame(StringRef Section, StringRef Prefix, StringRef Query, StringRef Category) const { - for (const auto &S : Sections) { - if (S.SectionMatcher->match(Section)) { - unsigned Blame = inSectionBlame(S.Entries, Prefix, Query, Category); + for (auto it = Sections.crbegin(); it != Sections.crend(); ++it) { + if (it->SectionMatcher->match(Section)) { + unsigned Blame = inSectionBlame(it->Entries, Prefix, Query, Category); if (Blame) return Blame; } diff --git a/llvm/unittests/Support/SpecialCaseListTest.cpp b/llvm/unittests/Support/SpecialCaseListTest.cpp index 4289a5e702155..ce58328f396b6 100644 --- a/llvm/unittests/Support/SpecialCaseListTest.cpp +++ b/llvm/unittests/Support/SpecialCaseListTest.cpp @@ -306,4 +306,27 @@ TEST_F(SpecialCaseListTest, Version2) { EXPECT_TRUE(SCL->inSection("sect2", "fun", "bar")); EXPECT_FALSE(SCL->inSection("sect3", "fun", "bar")); } + +TEST_F(SpecialCaseListTest, Version3) { + std::unique_ptr<SpecialCaseList> SCL = makeSpecialCaseList("[sect1]\n" + "src:foo*\n" + "[sect1]\n" + "src:bar*\n" + "src:def\n" + "[sect2]\n" + "src:def\n" + "src:de*\n"); + EXPECT_TRUE(SCL->inSection("sect1", "src", "fooz")); + EXPECT_TRUE(SCL->inSection("sect1", "src", "barz")); + EXPECT_FALSE(SCL->inSection("sect2", "src", "fooz")); + + EXPECT_TRUE(SCL->inSection("sect2", "src", "def")); + EXPECT_TRUE(SCL->inSection("sect1", "src", "def")); + + EXPECT_EQ(2u, SCL->inSectionBlame("sect1", "src", "fooz")); + EXPECT_EQ(4u, SCL->inSectionBlame("sect1", "src", "barz")); + EXPECT_EQ(5u, SCL->inSectionBlame("sect1", "src", "def")); + EXPECT_EQ(8u, SCL->inSectionBlame("sect2", "src", "def")); + EXPECT_EQ(8u, SCL->inSectionBlame("sect2", "src", "dez")); +} } >From d5508cc217f413b3bbb7a301b2110cfc0c2c6cbc Mon Sep 17 00:00:00 2001 From: Qinkun Bao <qin...@google.com> Date: Tue, 27 May 2025 03:24:26 +0000 Subject: [PATCH 2/4] Format SpecialCaseList.h Created using spr 1.3.6 --- llvm/include/llvm/Support/SpecialCaseList.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/include/llvm/Support/SpecialCaseList.h b/llvm/include/llvm/Support/SpecialCaseList.h index bce337f553a93..d54b242a9c501 100644 --- a/llvm/include/llvm/Support/SpecialCaseList.h +++ b/llvm/include/llvm/Support/SpecialCaseList.h @@ -17,8 +17,8 @@ #include "llvm/Support/GlobPattern.h" #include "llvm/Support/Regex.h" #include <memory> -#include <utility> #include <string> +#include <utility> #include <vector> namespace llvm { >From b094fc2f5e3fe0d9b65f86a3f6eda04a6ab41e47 Mon Sep 17 00:00:00 2001 From: Qinkun Bao <qin...@google.com> Date: Tue, 27 May 2025 14:01:19 +0000 Subject: [PATCH 3/4] Remove irelevant format changes Created using spr 1.3.6 --- llvm/unittests/Support/SpecialCaseListTest.cpp | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/llvm/unittests/Support/SpecialCaseListTest.cpp b/llvm/unittests/Support/SpecialCaseListTest.cpp index da4c557e740e6..0fe6a427c0562 100644 --- a/llvm/unittests/Support/SpecialCaseListTest.cpp +++ b/llvm/unittests/Support/SpecialCaseListTest.cpp @@ -218,9 +218,8 @@ TEST_F(SpecialCaseListTest, NoTrigramsInARule) { } TEST_F(SpecialCaseListTest, RepetitiveRule) { - std::unique_ptr<SpecialCaseList> SCL = - makeSpecialCaseList("fun:*bar*bar*bar*bar*\n" - "fun:bar*\n"); + std::unique_ptr<SpecialCaseList> SCL = makeSpecialCaseList("fun:*bar*bar*bar*bar*\n" + "fun:bar*\n"); EXPECT_TRUE(SCL->inSection("", "fun", "bara")); EXPECT_FALSE(SCL->inSection("", "fun", "abara")); EXPECT_TRUE(SCL->inSection("", "fun", "barbarbarbar")); @@ -229,8 +228,7 @@ TEST_F(SpecialCaseListTest, RepetitiveRule) { } TEST_F(SpecialCaseListTest, SpecialSymbolRule) { - std::unique_ptr<SpecialCaseList> SCL = - makeSpecialCaseList("src:*c\\+\\+abi*\n"); + std::unique_ptr<SpecialCaseList> SCL = makeSpecialCaseList("src:*c\\+\\+abi*\n"); EXPECT_TRUE(SCL->inSection("", "src", "c++abi")); EXPECT_FALSE(SCL->inSection("", "src", "c\\+\\+abi")); } @@ -246,9 +244,8 @@ TEST_F(SpecialCaseListTest, PopularTrigram) { } TEST_F(SpecialCaseListTest, EscapedSymbols) { - std::unique_ptr<SpecialCaseList> SCL = - makeSpecialCaseList("src:*c\\+\\+abi*\n" - "src:*hello\\\\world*\n"); + std::unique_ptr<SpecialCaseList> SCL = makeSpecialCaseList("src:*c\\+\\+abi*\n" + "src:*hello\\\\world*\n"); EXPECT_TRUE(SCL->inSection("", "src", "dir/c++abi")); EXPECT_FALSE(SCL->inSection("", "src", "dir/c\\+\\+abi")); EXPECT_FALSE(SCL->inSection("", "src", "c\\+\\+abi")); >From a898b892432d1e7b27b671dc5cae3d9b17de1c65 Mon Sep 17 00:00:00 2001 From: Qinkun Bao <qin...@google.com> Date: Tue, 27 May 2025 20:11:16 -0700 Subject: [PATCH 4/4] NotFound Created using spr 1.3.6 --- llvm/include/llvm/Support/SpecialCaseList.h | 1 + llvm/lib/Support/SpecialCaseList.cpp | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/llvm/include/llvm/Support/SpecialCaseList.h b/llvm/include/llvm/Support/SpecialCaseList.h index b21c6a4931eb6..5d6f3a374bb6d 100644 --- a/llvm/include/llvm/Support/SpecialCaseList.h +++ b/llvm/include/llvm/Support/SpecialCaseList.h @@ -70,6 +70,7 @@ class FileSystem; /// --- class SpecialCaseList { public: + constexpr static std::pair<unsigned, unsigned> NotFound = {0, 0}; /// Parses the special case list entries from files. On failure, returns /// 0 and writes an error message to string. LLVM_ABI static std::unique_ptr<SpecialCaseList> diff --git a/llvm/lib/Support/SpecialCaseList.cpp b/llvm/lib/Support/SpecialCaseList.cpp index 00f3409e37f13..8d4e043bc1c9f 100644 --- a/llvm/lib/Support/SpecialCaseList.cpp +++ b/llvm/lib/Support/SpecialCaseList.cpp @@ -224,7 +224,7 @@ SpecialCaseList::inSectionBlame(StringRef Section, StringRef Prefix, return {S.FileIdx, Blame}; } } - return {0, 0}; + return NotFound; } unsigned SpecialCaseList::inSectionBlame(const SectionEntries &Entries, _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits