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

Reply via email to