Skip to content

Commit c1a320e

Browse files
qinkunbaosivan-shani
authored andcommitted
[UBSan] Support src:*=sanitize for multiple ignorelists. (llvm#141640)
See: llvm#139128 and llvm#140529 for the background. The introduction of these new tests (ubsan-src-ignorelist-category.test) `-fsanitize-ignorelist=%t/src.ignorelist -fsanitize-ignorelist=%t/src.ignorelist.contradict9` in this PR will not lead to failures in the previous implementation (without this PR). This is because the existing logic distinguishes between Sections in different ignorelists, even if their names are identical. The order of these Sections is preserved using a `vector`.
1 parent 8702aa7 commit c1a320e

File tree

4 files changed

+35
-21
lines changed

4 files changed

+35
-21
lines changed

clang/include/clang/Basic/SanitizerSpecialCaseList.h

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "llvm/ADT/StringRef.h"
2020
#include "llvm/Support/SpecialCaseList.h"
2121
#include <memory>
22+
#include <utility>
2223
#include <vector>
2324

2425
namespace llvm {
@@ -44,20 +45,24 @@ class SanitizerSpecialCaseList : public llvm::SpecialCaseList {
4445
StringRef Category = StringRef()) const;
4546

4647
// Query ignorelisted entries if any bit in Mask matches the entry's section.
47-
// Return 0 if not found. If found, return the line number (starts with 1).
48-
unsigned inSectionBlame(SanitizerMask Mask, StringRef Prefix, StringRef Query,
49-
StringRef Category = StringRef()) const;
48+
// Return NotFound (0,0) if not found. If found, return the file index number
49+
// and the line number (FileIdx, LineNo) (FileIdx starts with 1 and LineNo
50+
// starts with 0).
51+
std::pair<unsigned, unsigned>
52+
inSectionBlame(SanitizerMask Mask, StringRef Prefix, StringRef Query,
53+
StringRef Category = StringRef()) const;
5054

5155
protected:
5256
// Initialize SanitizerSections.
5357
void createSanitizerSections();
5458

5559
struct SanitizerSection {
56-
SanitizerSection(SanitizerMask SM, SectionEntries &E)
57-
: Mask(SM), Entries(E) {};
60+
SanitizerSection(SanitizerMask SM, SectionEntries &E, unsigned idx)
61+
: Mask(SM), Entries(E), FileIdx(idx) {};
5862

5963
SanitizerMask Mask;
6064
SectionEntries &Entries;
65+
unsigned FileIdx;
6166
};
6267

6368
std::vector<SanitizerSection> SanitizerSections;

clang/lib/Basic/NoSanitizeList.cpp

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -44,13 +44,11 @@ bool NoSanitizeList::containsFunction(SanitizerMask Mask,
4444

4545
bool NoSanitizeList::containsFile(SanitizerMask Mask, StringRef FileName,
4646
StringRef Category) const {
47-
unsigned NoSanLine = SSCL->inSectionBlame(Mask, "src", FileName, Category);
48-
if (NoSanLine == 0)
47+
auto NoSan = SSCL->inSectionBlame(Mask, "src", FileName, Category);
48+
if (NoSan == llvm::SpecialCaseList::NotFound)
4949
return false;
50-
unsigned SanLine = SSCL->inSectionBlame(Mask, "src", FileName, "sanitize");
51-
// If we have two cases such as `src:a.cpp=sanitize` and `src:a.cpp`, the
52-
// current entry override the previous entry.
53-
return !SanLine || NoSanLine > SanLine;
50+
auto San = SSCL->inSectionBlame(Mask, "src", FileName, "sanitize");
51+
return San == llvm::SpecialCaseList::NotFound || NoSan > San;
5452
}
5553

5654
bool NoSanitizeList::containsMainFile(SanitizerMask Mask, StringRef FileName,

clang/lib/Basic/SanitizerSpecialCaseList.cpp

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -50,27 +50,27 @@ void SanitizerSpecialCaseList::createSanitizerSections() {
5050
#undef SANITIZER
5151
#undef SANITIZER_GROUP
5252

53-
SanitizerSections.emplace_back(Mask, S.Entries);
53+
SanitizerSections.emplace_back(Mask, S.Entries, S.FileIdx);
5454
}
5555
}
5656

5757
bool SanitizerSpecialCaseList::inSection(SanitizerMask Mask, StringRef Prefix,
5858
StringRef Query,
5959
StringRef Category) const {
60-
return inSectionBlame(Mask, Prefix, Query, Category);
60+
return inSectionBlame(Mask, Prefix, Query, Category) != NotFound;
6161
}
6262

63-
unsigned SanitizerSpecialCaseList::inSectionBlame(SanitizerMask Mask,
64-
StringRef Prefix,
65-
StringRef Query,
66-
StringRef Category) const {
63+
std::pair<unsigned, unsigned>
64+
SanitizerSpecialCaseList::inSectionBlame(SanitizerMask Mask, StringRef Prefix,
65+
StringRef Query,
66+
StringRef Category) const {
6767
for (const auto &S : llvm::reverse(SanitizerSections)) {
6868
if (S.Mask & Mask) {
69-
unsigned lineNum =
69+
unsigned LineNum =
7070
SpecialCaseList::inSectionBlame(S.Entries, Prefix, Query, Category);
71-
if (lineNum > 0)
72-
return lineNum;
71+
if (LineNum > 0)
72+
return {S.FileIdx, LineNum};
7373
}
7474
}
75-
return 0;
75+
return NotFound;
7676
}

clang/test/CodeGen/ubsan-src-ignorelist-category.test

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@
1212
// 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
1313
// 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
1414
// 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
15+
// RUN: %clang_cc1 -triple x86_64-linux-gnu -fsanitize=signed-integer-overflow -fsanitize-ignorelist=%t/src.ignorelist -fsanitize-ignorelist=%t/src.ignorelist.contradict9 -emit-llvm %t/test1.c -o - | FileCheck %s --check-prefixes=CHECK1,IGNORE
16+
// RUN: %clang_cc1 -triple x86_64-linux-gnu -fsanitize=signed-integer-overflow -fsanitize-ignorelist=%t/src.ignorelist.contradict9 -fsanitize-ignorelist=%t/src.ignorelist -emit-llvm %t/test1.c -o - | FileCheck %s --check-prefixes=CHECK1,SANITIZE
17+
1518

1619
// Verify ubsan only emits checks for files in the allowlist
1720

@@ -77,6 +80,14 @@ src:*/tes*1.c=sanitize
7780
src:*/te*t1.c
7881
src:*/t*st1.c=sanitize
7982

83+
//--- src.ignorelist.contradict9
84+
src:*
85+
src:*/test1.c=sanitize
86+
src:*/test1.c
87+
src:*/test1.c=sanitize
88+
src:*/te*t1.c
89+
src:*/test*.c
90+
8091

8192
//--- test1.c
8293
// CHECK1-LABEL: define dso_local i32 @add

0 commit comments

Comments
 (0)