[UBSan] Support src:*=sanitize for multiple ignorelists. (#141640)
See: https://github.com/llvm/llvm-project/issues/139128 and https://github.com/llvm/llvm-project/pull/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`.
This commit is contained in:
parent
3e0e567ab9
commit
45b874bc57
@ -19,6 +19,7 @@
|
|||||||
#include "llvm/ADT/StringRef.h"
|
#include "llvm/ADT/StringRef.h"
|
||||||
#include "llvm/Support/SpecialCaseList.h"
|
#include "llvm/Support/SpecialCaseList.h"
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
@ -44,8 +45,11 @@ public:
|
|||||||
StringRef Category = StringRef()) const;
|
StringRef Category = StringRef()) const;
|
||||||
|
|
||||||
// Query ignorelisted entries if any bit in Mask matches the entry's section.
|
// 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).
|
// Return NotFound (0,0) if not found. If found, return the file index number
|
||||||
unsigned inSectionBlame(SanitizerMask Mask, StringRef Prefix, StringRef Query,
|
// and the line number (FileIdx, LineNo) (FileIdx starts with 1 and LineNo
|
||||||
|
// starts with 0).
|
||||||
|
std::pair<unsigned, unsigned>
|
||||||
|
inSectionBlame(SanitizerMask Mask, StringRef Prefix, StringRef Query,
|
||||||
StringRef Category = StringRef()) const;
|
StringRef Category = StringRef()) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@ -53,11 +57,12 @@ protected:
|
|||||||
void createSanitizerSections();
|
void createSanitizerSections();
|
||||||
|
|
||||||
struct SanitizerSection {
|
struct SanitizerSection {
|
||||||
SanitizerSection(SanitizerMask SM, SectionEntries &E)
|
SanitizerSection(SanitizerMask SM, SectionEntries &E, unsigned idx)
|
||||||
: Mask(SM), Entries(E) {};
|
: Mask(SM), Entries(E), FileIdx(idx) {};
|
||||||
|
|
||||||
SanitizerMask Mask;
|
SanitizerMask Mask;
|
||||||
SectionEntries &Entries;
|
SectionEntries &Entries;
|
||||||
|
unsigned FileIdx;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::vector<SanitizerSection> SanitizerSections;
|
std::vector<SanitizerSection> SanitizerSections;
|
||||||
|
@ -44,13 +44,11 @@ bool NoSanitizeList::containsFunction(SanitizerMask Mask,
|
|||||||
|
|
||||||
bool NoSanitizeList::containsFile(SanitizerMask Mask, StringRef FileName,
|
bool NoSanitizeList::containsFile(SanitizerMask Mask, StringRef FileName,
|
||||||
StringRef Category) const {
|
StringRef Category) const {
|
||||||
unsigned NoSanLine = SSCL->inSectionBlame(Mask, "src", FileName, Category);
|
auto NoSan = SSCL->inSectionBlame(Mask, "src", FileName, Category);
|
||||||
if (NoSanLine == 0)
|
if (NoSan == llvm::SpecialCaseList::NotFound)
|
||||||
return false;
|
return false;
|
||||||
unsigned SanLine = SSCL->inSectionBlame(Mask, "src", FileName, "sanitize");
|
auto San = SSCL->inSectionBlame(Mask, "src", FileName, "sanitize");
|
||||||
// If we have two cases such as `src:a.cpp=sanitize` and `src:a.cpp`, the
|
return San == llvm::SpecialCaseList::NotFound || NoSan > San;
|
||||||
// current entry override the previous entry.
|
|
||||||
return !SanLine || NoSanLine > SanLine;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NoSanitizeList::containsMainFile(SanitizerMask Mask, StringRef FileName,
|
bool NoSanitizeList::containsMainFile(SanitizerMask Mask, StringRef FileName,
|
||||||
|
@ -50,27 +50,27 @@ void SanitizerSpecialCaseList::createSanitizerSections() {
|
|||||||
#undef SANITIZER
|
#undef SANITIZER
|
||||||
#undef SANITIZER_GROUP
|
#undef SANITIZER_GROUP
|
||||||
|
|
||||||
SanitizerSections.emplace_back(Mask, S.Entries);
|
SanitizerSections.emplace_back(Mask, S.Entries, S.FileIdx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SanitizerSpecialCaseList::inSection(SanitizerMask Mask, StringRef Prefix,
|
bool SanitizerSpecialCaseList::inSection(SanitizerMask Mask, StringRef Prefix,
|
||||||
StringRef Query,
|
StringRef Query,
|
||||||
StringRef Category) const {
|
StringRef Category) const {
|
||||||
return inSectionBlame(Mask, Prefix, Query, Category);
|
return inSectionBlame(Mask, Prefix, Query, Category) != NotFound;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned SanitizerSpecialCaseList::inSectionBlame(SanitizerMask Mask,
|
std::pair<unsigned, unsigned>
|
||||||
StringRef Prefix,
|
SanitizerSpecialCaseList::inSectionBlame(SanitizerMask Mask, StringRef Prefix,
|
||||||
StringRef Query,
|
StringRef Query,
|
||||||
StringRef Category) const {
|
StringRef Category) const {
|
||||||
for (const auto &S : llvm::reverse(SanitizerSections)) {
|
for (const auto &S : llvm::reverse(SanitizerSections)) {
|
||||||
if (S.Mask & Mask) {
|
if (S.Mask & Mask) {
|
||||||
unsigned lineNum =
|
unsigned LineNum =
|
||||||
SpecialCaseList::inSectionBlame(S.Entries, Prefix, Query, Category);
|
SpecialCaseList::inSectionBlame(S.Entries, Prefix, Query, Category);
|
||||||
if (lineNum > 0)
|
if (LineNum > 0)
|
||||||
return lineNum;
|
return {S.FileIdx, LineNum};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return NotFound;
|
||||||
}
|
}
|
||||||
|
@ -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.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.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 -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 -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 -emit-llvm %t/test1.c -o - | FileCheck %s --check-prefixes=CHECK1,SANITIZE
|
||||||
|
|
||||||
|
|
||||||
// Verify ubsan only emits checks for files in the allowlist
|
// Verify ubsan only emits checks for files in the allowlist
|
||||||
|
|
||||||
@ -77,6 +80,14 @@ src:*/tes*1.c=sanitize
|
|||||||
src:*/te*t1.c
|
src:*/te*t1.c
|
||||||
src:*/t*st1.c=sanitize
|
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
|
//--- test1.c
|
||||||
// CHECK1-LABEL: define dso_local i32 @add
|
// CHECK1-LABEL: define dso_local i32 @add
|
||||||
|
Loading…
x
Reference in New Issue
Block a user