[llvm-branch-commits] [UBSan] Support src:*=sanitize for multiple ignorelists. (PR #141640)

via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Tue May 27 10:33:12 PDT 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Qinkun Bao (qinkunbao)

<details>
<summary>Changes</summary>

See: https://github.com/llvm/llvm-project/issues/139128 for the background.


---
Full diff: https://github.com/llvm/llvm-project/pull/141640.diff


4 Files Affected:

- (modified) clang/include/clang/Basic/SanitizerSpecialCaseList.h (+9-5) 
- (modified) clang/lib/Basic/NoSanitizeList.cpp (+6-3) 
- (modified) clang/lib/Basic/SanitizerSpecialCaseList.cpp (+9-8) 
- (modified) clang/test/CodeGen/ubsan-src-ignorelist-category.test (+11) 


``````````diff
diff --git a/clang/include/clang/Basic/SanitizerSpecialCaseList.h b/clang/include/clang/Basic/SanitizerSpecialCaseList.h
index 25d518e7128cf..a19392399bfd7 100644
--- a/clang/include/clang/Basic/SanitizerSpecialCaseList.h
+++ b/clang/include/clang/Basic/SanitizerSpecialCaseList.h
@@ -19,6 +19,7 @@
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Support/SpecialCaseList.h"
 #include <memory>
+#include <utility>
 #include <vector>
 
 namespace llvm {
@@ -44,20 +45,23 @@ class SanitizerSpecialCaseList : public llvm::SpecialCaseList {
                  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;
+  // Return (0,0 if not found. If found, return the file index number and the
+  // line number (FileIdx, LineNo) (all start with 1).
+  std::pair<unsigned, 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) {};
+    SanitizerSection(SanitizerMask SM, SectionEntries &E, unsigned idx)
+        : Mask(SM), Entries(E), FileIdx(idx) {};
 
     SanitizerMask Mask;
     SectionEntries &Entries;
+    unsigned FileIdx;
   };
 
   std::vector<SanitizerSection> SanitizerSections;
diff --git a/clang/lib/Basic/NoSanitizeList.cpp b/clang/lib/Basic/NoSanitizeList.cpp
index 4feef5c6ea052..c58a67971dfb6 100644
--- a/clang/lib/Basic/NoSanitizeList.cpp
+++ b/clang/lib/Basic/NoSanitizeList.cpp
@@ -44,14 +44,17 @@ bool NoSanitizeList::containsFunction(SanitizerMask Mask,
 
 bool NoSanitizeList::containsFile(SanitizerMask Mask, StringRef FileName,
                                   StringRef Category) const {
-  unsigned NoSanLine = SSCL->inSectionBlame(Mask, "src", FileName, Category);
+  auto [NoSanFileIdx, NoSanLine] =
+      SSCL->inSectionBlame(Mask, "src", FileName, Category);
   if (NoSanLine == 0)
     return false;
-  unsigned SanLine = SSCL->inSectionBlame(Mask, "src", FileName, "sanitize");
+  auto [SanFileIdx, 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 std::make_pair(NoSanFileIdx, NoSanLine) >
+           std::make_pair(SanFileIdx, SanLine);
   return true;
 }
 
diff --git a/clang/lib/Basic/SanitizerSpecialCaseList.cpp b/clang/lib/Basic/SanitizerSpecialCaseList.cpp
index 4508d705eb43a..0b2c0f9c4478a 100644
--- a/clang/lib/Basic/SanitizerSpecialCaseList.cpp
+++ b/clang/lib/Basic/SanitizerSpecialCaseList.cpp
@@ -49,28 +49,29 @@ void SanitizerSpecialCaseList::createSanitizerSections() {
 #undef SANITIZER
 #undef SANITIZER_GROUP
 
-    SanitizerSections.emplace_back(Mask, S.Entries);
+    SanitizerSections.emplace_back(Mask, S.Entries, S.FileIdx);
   }
 }
 
 bool SanitizerSpecialCaseList::inSection(SanitizerMask Mask, StringRef Prefix,
                                          StringRef Query,
                                          StringRef Category) const {
-  return inSectionBlame(Mask, Prefix, Query, Category);
+  auto [FileIdx, LineNo] = inSectionBlame(Mask, Prefix, Query, Category);
+  return FileIdx;
 }
 
-unsigned SanitizerSpecialCaseList::inSectionBlame(SanitizerMask Mask,
-                                                  StringRef Prefix,
-                                                  StringRef Query,
-                                                  StringRef Category) const {
+std::pair<unsigned, 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 {it->FileIdx, lineNum};
     }
   }
-  return 0;
+  return {0, 0};
 }
diff --git a/clang/test/CodeGen/ubsan-src-ignorelist-category.test b/clang/test/CodeGen/ubsan-src-ignorelist-category.test
index 55967ec77c836..0ff2ea5c456a1 100644
--- a/clang/test/CodeGen/ubsan-src-ignorelist-category.test
+++ b/clang/test/CodeGen/ubsan-src-ignorelist-category.test
@@ -12,6 +12,9 @@
 // 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
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -fsanitize=signed-integer-overflow -fsanitize-ignorelist=%t/src.ignorelist.contradict8 -fsanitize-ignorelist=%t/src.ignorelist.contradict9 -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.contradict9 -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
 
@@ -77,6 +80,14 @@ src:*/tes*1.c=sanitize
 src:*/te*t1.c
 src:*/t*st1.c=sanitize
 
+//--- src.ignorelist.contradict9
+src:*
+src:*/test1.c=sanitize
+src:*/test1.c
+src:*/test1.c=sanitize
+src:*/te*t1.c
+src:*/test*.c
+
 
 //--- test1.c
 // CHECK1-LABEL: define dso_local i32 @add

``````````

</details>


https://github.com/llvm/llvm-project/pull/141640


More information about the llvm-branch-commits mailing list