Skip to content

fix: replace report_fatal_error with Diags and exit #147959

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Jul 25, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions clang/include/clang/AST/ASTContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -634,6 +634,8 @@ class ASTContext : public RefCountedBase<ASTContext> {
void setRelocationInfoForCXXRecord(const CXXRecordDecl *,
CXXRecordDeclRelocationInfo);

void initSanitizers(const LangOptions &LangOpts, SourceManager &SM);

/// Examines a given type, and returns whether the type itself
/// is address discriminated, or any transitively embedded types
/// contain data that is address discriminated. This includes
Expand Down
8 changes: 4 additions & 4 deletions clang/include/clang/Basic/DiagnosticDriverKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -252,13 +252,13 @@ def err_drv_invalid_argument_to_option : Error<
def err_drv_missing_sanitizer_ignorelist : Error<
"missing sanitizer ignorelist: '%0'">;
def err_drv_malformed_sanitizer_ignorelist : Error<
"malformed sanitizer ignorelist: '%0'">;
"failed to %select{load|parse}0 malformed sanitizer ignorelist: '%1'">;
def err_drv_malformed_sanitizer_coverage_allowlist : Error<
"malformed sanitizer coverage allowlist: '%0'">;
"failed to %select{load|parse}0 malformed sanitizer coverage allowlist: '%1'">;
def err_drv_malformed_sanitizer_coverage_ignorelist : Error<
"malformed sanitizer coverage ignorelist: '%0'">;
"failed to %select{load|parse}0 malformed sanitizer coverage ignorelist: '%1'">;
def err_drv_malformed_sanitizer_metadata_ignorelist : Error<
"malformed sanitizer metadata ignorelist: '%0'">;
"failed to %select{load|parse}0 malformed sanitizer metadata ignorelist: '%1'">;
def err_drv_unsupported_static_sanitizer_darwin : Error<
"static %0 runtime is not supported on darwin">;
def err_drv_duplicate_config : Error<
Expand Down
2 changes: 2 additions & 0 deletions clang/include/clang/Basic/DiagnosticFrontendKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,8 @@ def warn_profile_data_misexpect : Warning<
"potential performance regression from use of __builtin_expect(): "
"annotation was correct on %0 of profiled executions">,
BackendInfo, InGroup<MisExpect>;
def err_sanitize_ignorelist_failure : Error<
"failed to %select{load|parse}0 sanitizer ignorelist file: '%1'">;
} // end of instrumentation issue category

def err_extract_api_ignores_file_not_found :
Expand Down
5 changes: 3 additions & 2 deletions clang/include/clang/Basic/NoSanitizeList.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,10 @@ class NoSanitizeList {
StringRef Category) const;

public:
NoSanitizeList(const std::vector<std::string> &NoSanitizeListPaths,
SourceManager &SM);
NoSanitizeList(SourceManager &SM);
~NoSanitizeList();
bool init(const std::vector<std::string> &Paths,
std::pair<unsigned, std::string> &Error);
bool containsGlobal(SanitizerMask Mask, StringRef GlobalName,
StringRef Category = StringRef()) const;
bool containsType(SanitizerMask Mask, StringRef MangledTypeName,
Expand Down
7 changes: 2 additions & 5 deletions clang/include/clang/Basic/SanitizerSpecialCaseList.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#ifndef LLVM_CLANG_BASIC_SANITIZERSPECIALCASELIST_H
#define LLVM_CLANG_BASIC_SANITIZERSPECIALCASELIST_H

#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/LLVM.h"
#include "clang/Basic/Sanitizers.h"
#include "llvm/ADT/StringRef.h"
Expand All @@ -34,11 +35,7 @@ class SanitizerSpecialCaseList : public llvm::SpecialCaseList {
public:
static std::unique_ptr<SanitizerSpecialCaseList>
create(const std::vector<std::string> &Paths, llvm::vfs::FileSystem &VFS,
std::string &Error);

static std::unique_ptr<SanitizerSpecialCaseList>
createOrDie(const std::vector<std::string> &Paths,
llvm::vfs::FileSystem &VFS);
std::pair<unsigned, std::string> &Error);

// Query ignorelisted entries if any bit in Mask matches the entry's section.
bool inSection(SanitizerMask Mask, StringRef Prefix, StringRef Query,
Expand Down
12 changes: 11 additions & 1 deletion clang/lib/AST/ASTContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
#include "clang/Basic/AddressSpaces.h"
#include "clang/Basic/Builtins.h"
#include "clang/Basic/CommentOptions.h"
#include "clang/Basic/DiagnosticFrontend.h"
#include "clang/Basic/ExceptionSpecificationType.h"
#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/LLVM.h"
Expand Down Expand Up @@ -944,7 +945,7 @@ ASTContext::ASTContext(LangOptions &LOpts, SourceManager &SM,
DependentBitIntTypes(this_()), SubstTemplateTemplateParmPacks(this_()),
DeducedTemplates(this_()), ArrayParameterTypes(this_()),
CanonTemplateTemplateParms(this_()), SourceMgr(SM), LangOpts(LOpts),
NoSanitizeL(new NoSanitizeList(LangOpts.NoSanitizeFiles, SM)),
NoSanitizeL(new NoSanitizeList(SM)),
XRayFilter(new XRayFunctionFilter(LangOpts.XRayAlwaysInstrumentFiles,
LangOpts.XRayNeverInstrumentFiles,
LangOpts.XRayAttrListFiles, SM)),
Expand Down Expand Up @@ -1697,6 +1698,15 @@ ASTContext::getRelocationInfoForCXXRecord(const CXXRecordDecl *RD) const {
return std::nullopt;
}

void ASTContext::initSanitizers(const LangOptions &LangOpts,
SourceManager &SM) {
std::pair<unsigned, std::string> Error;
if (!NoSanitizeL->init(LangOpts.NoSanitizeFiles, Error)) {
SM.getDiagnostics().Report(diag::err_sanitize_ignorelist_failure)
<< Error.first << Error.second;
}
}

void ASTContext::setRelocationInfoForCXXRecord(
const CXXRecordDecl *RD, CXXRecordDeclRelocationInfo Info) {
assert(RD);
Expand Down
13 changes: 8 additions & 5 deletions clang/lib/Basic/NoSanitizeList.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,7 @@

using namespace clang;

NoSanitizeList::NoSanitizeList(const std::vector<std::string> &NoSanitizePaths,
SourceManager &SM)
: SSCL(SanitizerSpecialCaseList::createOrDie(
NoSanitizePaths, SM.getFileManager().getVirtualFileSystem())),
SM(SM) {}
NoSanitizeList::NoSanitizeList(SourceManager &SM) : SM(SM) {}

NoSanitizeList::~NoSanitizeList() = default;

Expand All @@ -42,6 +38,13 @@ bool NoSanitizeList::containsPrefix(SanitizerMask Mask, StringRef Prefix,
return San == llvm::SpecialCaseList::NotFound || NoSan > San;
}

bool NoSanitizeList::init(const std::vector<std::string> &Paths,
std::pair<unsigned, std::string> &Error) {
SSCL = SanitizerSpecialCaseList::create(
Paths, SM.getFileManager().getVirtualFileSystem(), Error);
return SSCL != nullptr;
}

bool NoSanitizeList::containsGlobal(SanitizerMask Mask, StringRef GlobalName,
StringRef Category) const {
return containsPrefix(Mask, "global", GlobalName, Category);
Expand Down
10 changes: 6 additions & 4 deletions clang/lib/Basic/ProfileList.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ class ProfileSpecialCaseList : public llvm::SpecialCaseList {
public:
static std::unique_ptr<ProfileSpecialCaseList>
create(const std::vector<std::string> &Paths, llvm::vfs::FileSystem &VFS,
std::string &Error);
std::pair<unsigned, std::string> &Error);

static std::unique_ptr<ProfileSpecialCaseList>
createOrDie(const std::vector<std::string> &Paths,
Expand All @@ -44,7 +44,8 @@ class ProfileSpecialCaseList : public llvm::SpecialCaseList {

std::unique_ptr<ProfileSpecialCaseList>
ProfileSpecialCaseList::create(const std::vector<std::string> &Paths,
llvm::vfs::FileSystem &VFS, std::string &Error) {
llvm::vfs::FileSystem &VFS,
std::pair<unsigned, std::string> &Error) {
auto PSCL = std::make_unique<ProfileSpecialCaseList>();
if (PSCL->createInternal(Paths, VFS, Error))
return PSCL;
Expand All @@ -54,10 +55,11 @@ ProfileSpecialCaseList::create(const std::vector<std::string> &Paths,
std::unique_ptr<ProfileSpecialCaseList>
ProfileSpecialCaseList::createOrDie(const std::vector<std::string> &Paths,
llvm::vfs::FileSystem &VFS) {
std::string Error;
std::pair<unsigned, std::string> Error;
if (auto PSCL = create(Paths, VFS, Error))
return PSCL;
llvm::report_fatal_error(llvm::Twine(Error));
// TODO: add init function and use diagnose instead fo report_fatal_error
llvm::report_fatal_error(llvm::Twine(Error.second));
}

} // namespace clang
Expand Down
11 changes: 1 addition & 10 deletions clang/lib/Basic/SanitizerSpecialCaseList.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ using namespace clang;
std::unique_ptr<SanitizerSpecialCaseList>
SanitizerSpecialCaseList::create(const std::vector<std::string> &Paths,
llvm::vfs::FileSystem &VFS,
std::string &Error) {
std::pair<unsigned, std::string> &Error) {
std::unique_ptr<clang::SanitizerSpecialCaseList> SSCL(
new SanitizerSpecialCaseList());
if (SSCL->createInternal(Paths, VFS, Error)) {
Expand All @@ -28,15 +28,6 @@ SanitizerSpecialCaseList::create(const std::vector<std::string> &Paths,
return nullptr;
}

std::unique_ptr<SanitizerSpecialCaseList>
SanitizerSpecialCaseList::createOrDie(const std::vector<std::string> &Paths,
llvm::vfs::FileSystem &VFS) {
std::string Error;
if (auto SSCL = create(Paths, VFS, Error))
return SSCL;
llvm::report_fatal_error(StringRef(Error));
}

void SanitizerSpecialCaseList::createSanitizerSections() {
for (auto &S : Sections) {
SanitizerMask Mask;
Expand Down
4 changes: 2 additions & 2 deletions clang/lib/Driver/SanitizerArgs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -181,11 +181,11 @@ static void validateSpecialCaseListFormat(const Driver &D,
if (SCLFiles.empty())
return;

std::string BLError;
std::pair<unsigned, std::string> BLError;
std::unique_ptr<llvm::SpecialCaseList> SCL(
llvm::SpecialCaseList::create(SCLFiles, D.getVFS(), BLError));
if (!SCL && DiagnoseErrors)
D.Diag(MalformedSCLErrorDiagID) << BLError;
D.Diag(MalformedSCLErrorDiagID) << BLError.first << BLError.second;
}

static void addDefaultIgnorelists(const Driver &D, SanitizerMask Kinds,
Expand Down
1 change: 1 addition & 0 deletions clang/lib/Frontend/CompilerInstance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -554,6 +554,7 @@ void CompilerInstance::createASTContext() {
PP.getBuiltinInfo(), PP.TUKind);
Context->InitBuiltinTypes(getTarget(), getAuxTarget());
setASTContext(Context);
Context->initSanitizers(getLangOpts(), PP.getSourceManager());
}

// ExternalASTSource
Expand Down
9 changes: 8 additions & 1 deletion clang/test/Driver/fsanitize-ignorelist.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@

// Driver properly reports malformed ignorelist files.
// RUN: not %clang --target=x86_64-linux-gnu -fsanitize=address -fsanitize-ignorelist=%t.second -fsanitize-ignorelist=%t.bad -fsanitize-ignorelist=%t.good %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-BAD-IGNORELIST
// CHECK-BAD-IGNORELIST: error: malformed sanitizer ignorelist: 'error parsing file '{{.*}}.bad': malformed line 1: 'badline''
// CHECK-BAD-IGNORELIST: error: failed to parse malformed sanitizer ignorelist: ''{{.*}}.bad': malformed line 1: 'badline'

// -fno-sanitize-ignorelist disables all ignorelists specified earlier.
// RUN: %clang --target=x86_64-linux-gnu -fsanitize=address -fsanitize-ignorelist=%t.good -fno-sanitize-ignorelist -fsanitize-ignorelist=%t.second %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ONLY-FIRST-DISABLED --implicit-check-not=-fsanitize-ignorelist=
Expand All @@ -71,3 +71,10 @@
// CHECK-MISSING-CFI-NO-IGNORELIST-NOT: error: no such file or directory: '{{.*}}cfi_ignorelist.txt'

// DELIMITERS: {{^ *"}}

// Check that a missing file passed to -fsanitize-system-ignorelist triggers a clean error without crashing.
// RUN: not %clang --target=x86_64-linux-gnu -Xclang -fsanitize-system-ignorelist=%t.nonexistent %s -c -o /dev/null 2>&1 | FileCheck %s --check-prefix=CHECK-SYSTEM-IGNORELIST-NOFILE
// CHECK-SYSTEM-IGNORELIST-NOFILE: error: failed to load sanitizer ignorelist file: ''{{.*[\\/]fsanitize-ignorelist\.c\.tmp\.nonexistent}}': {{[Nn]o such file or directory}}
// CHECK-SYSTEM-IGNORELIST-NOFILE-NOT: Stack dump:
// CHECK-SYSTEM-IGNORELIST-NOFILE-NOT: PLEASE submit a bug report
// CHECK-SYSTEM-IGNORELIST-NOFILE-NOT: diagnostic msg:
8 changes: 7 additions & 1 deletion llvm/include/llvm/Support/SpecialCaseList.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,11 @@ class SpecialCaseList {
public:
static constexpr std::pair<unsigned, unsigned> NotFound = {0, 0};
/// Parses the special case list entries from files. On failure, returns
/// std::pair Error, Error.first is error enum, Error.second is error message.
LLVM_ABI static std::unique_ptr<SpecialCaseList>
create(const std::vector<std::string> &Paths, llvm::vfs::FileSystem &FS,
std::pair<unsigned, std::string> &Error);
/// 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>
create(const std::vector<std::string> &Paths, llvm::vfs::FileSystem &FS,
Expand Down Expand Up @@ -111,7 +116,8 @@ class SpecialCaseList {
// Implementations of the create*() functions that can also be used by derived
// classes.
LLVM_ABI bool createInternal(const std::vector<std::string> &Paths,
vfs::FileSystem &VFS, std::string &Error);
vfs::FileSystem &VFS,
std::pair<unsigned, std::string> &Error);
LLVM_ABI bool createInternal(const MemoryBuffer *MB, std::string &Error);

SpecialCaseList() = default;
Expand Down
30 changes: 24 additions & 6 deletions llvm/lib/Support/SpecialCaseList.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,13 +79,28 @@ unsigned SpecialCaseList::Matcher::match(StringRef Query) const {
// TODO: Refactor this to return Expected<...>
std::unique_ptr<SpecialCaseList>
SpecialCaseList::create(const std::vector<std::string> &Paths,
llvm::vfs::FileSystem &FS, std::string &Error) {
llvm::vfs::FileSystem &FS,
std::pair<unsigned, std::string> &Error) {
std::unique_ptr<SpecialCaseList> SCL(new SpecialCaseList());
if (SCL->createInternal(Paths, FS, Error))
return SCL;
return nullptr;
}

std::unique_ptr<SpecialCaseList>
SpecialCaseList::create(const std::vector<std::string> &Paths,
llvm::vfs::FileSystem &FS, std::string &Error) {
std::pair<unsigned, std::string> Err;
std::unique_ptr<SpecialCaseList> SCL = create(Paths, FS, Err);
if (!SCL) {
assert(Err.first == 0 || Err.first == 1 && "Unexpected error kind");
const char *Prefix =
Err.first == 0 ? "can't open file " : "error parsing file ";
Error = (Twine(Prefix) + Err.second).str();
}
return SCL;
}

std::unique_ptr<SpecialCaseList> SpecialCaseList::create(const MemoryBuffer *MB,
std::string &Error) {
std::unique_ptr<SpecialCaseList> SCL(new SpecialCaseList());
Expand All @@ -97,25 +112,28 @@ std::unique_ptr<SpecialCaseList> SpecialCaseList::create(const MemoryBuffer *MB,
std::unique_ptr<SpecialCaseList>
SpecialCaseList::createOrDie(const std::vector<std::string> &Paths,
llvm::vfs::FileSystem &FS) {
std::string Error;
std::pair<unsigned, std::string> Error;
if (auto SCL = create(Paths, FS, Error))
return SCL;
report_fatal_error(Twine(Error));
report_fatal_error(Twine(Error.second));
}

bool SpecialCaseList::createInternal(const std::vector<std::string> &Paths,
vfs::FileSystem &VFS, std::string &Error) {
vfs::FileSystem &VFS,
std::pair<unsigned, std::string> &Error) {
for (size_t i = 0; i < Paths.size(); ++i) {
const auto &Path = Paths[i];
ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr =
VFS.getBufferForFile(Path);
if (std::error_code EC = FileOrErr.getError()) {
Error = (Twine("can't open file '") + Path + "': " + EC.message()).str();
Error.first = 0 /* open failure */;
Error.second = (Twine("'") + Path + "': " + EC.message()).str();
return false;
}
std::string ParseError;
if (!parse(i, FileOrErr.get().get(), ParseError)) {
Error = (Twine("error parsing file '") + Path + "': " + ParseError).str();
Error.first = 1 /* parse failure */;
Error.second = (Twine("'") + Path + "': " + ParseError).str();
return false;
}
}
Expand Down