Author: woruyu Date: 2025-07-25T10:20:30-04:00 New Revision: 9d3dd8efe07180a6b261ae617ffc1ee5e26419c9
URL: https://github.com/llvm/llvm-project/commit/9d3dd8efe07180a6b261ae617ffc1ee5e26419c9 DIFF: https://github.com/llvm/llvm-project/commit/9d3dd8efe07180a6b261ae617ffc1ee5e26419c9.diff LOG: fix: replace report_fatal_error with Diags and exit (#147959) report_fatal_error is not a good way to report diagnostics to the users, so this switches to using actual diagnostic reporting mechanisms instead. Fixes #147187 Added: Modified: clang/include/clang/AST/ASTContext.h clang/include/clang/Basic/DiagnosticDriverKinds.td clang/include/clang/Basic/DiagnosticFrontendKinds.td clang/include/clang/Basic/NoSanitizeList.h clang/include/clang/Basic/SanitizerSpecialCaseList.h clang/lib/AST/ASTContext.cpp clang/lib/Basic/NoSanitizeList.cpp clang/lib/Basic/ProfileList.cpp clang/lib/Basic/SanitizerSpecialCaseList.cpp clang/lib/Driver/SanitizerArgs.cpp clang/lib/Frontend/CompilerInstance.cpp clang/test/Driver/fsanitize-ignorelist.c llvm/include/llvm/Support/SpecialCaseList.h llvm/lib/Support/SpecialCaseList.cpp Removed: ################################################################################ diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h index 17cbfb2693308..c099e75f03949 100644 --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -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 diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td index 759ba0419bd45..230698d72273a 100644 --- a/clang/include/clang/Basic/DiagnosticDriverKinds.td +++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td @@ -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< diff --git a/clang/include/clang/Basic/DiagnosticFrontendKinds.td b/clang/include/clang/Basic/DiagnosticFrontendKinds.td index 8a8db27490f06..1f0b454cca023 100644 --- a/clang/include/clang/Basic/DiagnosticFrontendKinds.td +++ b/clang/include/clang/Basic/DiagnosticFrontendKinds.td @@ -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 : diff --git a/clang/include/clang/Basic/NoSanitizeList.h b/clang/include/clang/Basic/NoSanitizeList.h index a7a7a29d50a9a..b6f341d5e461a 100644 --- a/clang/include/clang/Basic/NoSanitizeList.h +++ b/clang/include/clang/Basic/NoSanitizeList.h @@ -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, diff --git a/clang/include/clang/Basic/SanitizerSpecialCaseList.h b/clang/include/clang/Basic/SanitizerSpecialCaseList.h index cf7485909e409..d7253eca2e0ee 100644 --- a/clang/include/clang/Basic/SanitizerSpecialCaseList.h +++ b/clang/include/clang/Basic/SanitizerSpecialCaseList.h @@ -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" @@ -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, diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 6b6275faa215a..c451c87249dc1 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -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" @@ -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)), @@ -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); diff --git a/clang/lib/Basic/NoSanitizeList.cpp b/clang/lib/Basic/NoSanitizeList.cpp index 96f79fb2a2a29..dc9ab8321f654 100644 --- a/clang/lib/Basic/NoSanitizeList.cpp +++ b/clang/lib/Basic/NoSanitizeList.cpp @@ -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; @@ -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); diff --git a/clang/lib/Basic/ProfileList.cpp b/clang/lib/Basic/ProfileList.cpp index 8481deffe2a7b..2b9f88eb8c5a0 100644 --- a/clang/lib/Basic/ProfileList.cpp +++ b/clang/lib/Basic/ProfileList.cpp @@ -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, @@ -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; @@ -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 diff --git a/clang/lib/Basic/SanitizerSpecialCaseList.cpp b/clang/lib/Basic/SanitizerSpecialCaseList.cpp index f7bc1d5545d75..c3729e964cb65 100644 --- a/clang/lib/Basic/SanitizerSpecialCaseList.cpp +++ b/clang/lib/Basic/SanitizerSpecialCaseList.cpp @@ -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)) { @@ -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; diff --git a/clang/lib/Driver/SanitizerArgs.cpp b/clang/lib/Driver/SanitizerArgs.cpp index 21e4cff6309c3..aa767ae3112db 100644 --- a/clang/lib/Driver/SanitizerArgs.cpp +++ b/clang/lib/Driver/SanitizerArgs.cpp @@ -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, diff --git a/clang/lib/Frontend/CompilerInstance.cpp b/clang/lib/Frontend/CompilerInstance.cpp index c7b82db292a14..bbb856b02e417 100644 --- a/clang/lib/Frontend/CompilerInstance.cpp +++ b/clang/lib/Frontend/CompilerInstance.cpp @@ -554,6 +554,7 @@ void CompilerInstance::createASTContext() { PP.getBuiltinInfo(), PP.TUKind); Context->InitBuiltinTypes(getTarget(), getAuxTarget()); setASTContext(Context); + Context->initSanitizers(getLangOpts(), PP.getSourceManager()); } // ExternalASTSource diff --git a/clang/test/Driver/fsanitize-ignorelist.c b/clang/test/Driver/fsanitize-ignorelist.c index 7dd666a453198..d3c8e6c1197f0 100644 --- a/clang/test/Driver/fsanitize-ignorelist.c +++ b/clang/test/Driver/fsanitize-ignorelist.c @@ -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= @@ -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: diff --git a/llvm/include/llvm/Support/SpecialCaseList.h b/llvm/include/llvm/Support/SpecialCaseList.h index 22a62eac9e01a..deec7d9a372df 100644 --- a/llvm/include/llvm/Support/SpecialCaseList.h +++ b/llvm/include/llvm/Support/SpecialCaseList.h @@ -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, @@ -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; diff --git a/llvm/lib/Support/SpecialCaseList.cpp b/llvm/lib/Support/SpecialCaseList.cpp index 8d4e043bc1c9f..2d91afb3ef20f 100644 --- a/llvm/lib/Support/SpecialCaseList.cpp +++ b/llvm/lib/Support/SpecialCaseList.cpp @@ -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()); @@ -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; } } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits