Skip to content

[clang] Reset FileID based diag state mappings #143695

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 1 commit into from
Jun 12, 2025

Conversation

kadircet
Copy link
Member

When sharing same compiler instance for multiple compilations, we reset
source manager's file id tables in between runs. Diagnostics engine
keeps a cache based on these file ids, that became dangling references
across compilations.

This patch makes sure we reset those whenever sourcemanager is trashing
its FileIDs.

When sharing same compiler instance for multiple compilations, we reset
source manager's file id tables in between runs. Diagnostics engine
keeps a cache based on these file ids, that became dangling references
across compilations.

This patch makes sure we reset those whenever sourcemanager is trashing
its FileIDs.
@llvmbot llvmbot added clang Clang issues not falling into any other category clang:frontend Language frontend issues, e.g. anything involving "Sema" labels Jun 11, 2025
@llvmbot
Copy link
Member

llvmbot commented Jun 11, 2025

@llvm/pr-subscribers-clang

Author: kadir çetinkaya (kadircet)

Changes

When sharing same compiler instance for multiple compilations, we reset
source manager's file id tables in between runs. Diagnostics engine
keeps a cache based on these file ids, that became dangling references
across compilations.

This patch makes sure we reset those whenever sourcemanager is trashing
its FileIDs.


Full diff: https://github.com/llvm/llvm-project/pull/143695.diff

4 Files Affected:

  • (modified) clang/include/clang/Basic/Diagnostic.h (+10-3)
  • (modified) clang/lib/Basic/Diagnostic.cpp (+3-1)
  • (modified) clang/lib/Basic/SourceManager.cpp (+3)
  • (modified) clang/unittests/Frontend/CompilerInstanceTest.cpp (+51)
diff --git a/clang/include/clang/Basic/Diagnostic.h b/clang/include/clang/Basic/Diagnostic.h
index e9c54c3c487c9..b5cbda9e31049 100644
--- a/clang/include/clang/Basic/Diagnostic.h
+++ b/clang/include/clang/Basic/Diagnostic.h
@@ -420,10 +420,13 @@ class DiagnosticsEngine : public RefCountedBase<DiagnosticsEngine> {
     bool empty() const { return Files.empty(); }
 
     /// Clear out this map.
-    void clear() {
+    void clear(bool Soft) {
+      // Just clear the cache when in soft mode.
       Files.clear();
-      FirstDiagState = CurDiagState = nullptr;
-      CurDiagStateLoc = SourceLocation();
+      if (!Soft) {
+        FirstDiagState = CurDiagState = nullptr;
+        CurDiagStateLoc = SourceLocation();
+      }
     }
 
     /// Produce a debugging dump of the diagnostic state.
@@ -918,6 +921,10 @@ class DiagnosticsEngine : public RefCountedBase<DiagnosticsEngine> {
   /// Reset the state of the diagnostic object to its initial configuration.
   /// \param[in] soft - if true, doesn't reset the diagnostic mappings and state
   void Reset(bool soft = false);
+  /// We keep a cache of FileIDs for diagnostics mapped by pragmas. These might
+  /// get invalidated when diagnostics engine is shared across different
+  /// compilations. Provide users with a way to reset that.
+  void ResetPragmas();
 
   //===--------------------------------------------------------------------===//
   // DiagnosticsEngine classification and reporting interfaces.
diff --git a/clang/lib/Basic/Diagnostic.cpp b/clang/lib/Basic/Diagnostic.cpp
index 694224071347a..6d4f2ba68072f 100644
--- a/clang/lib/Basic/Diagnostic.cpp
+++ b/clang/lib/Basic/Diagnostic.cpp
@@ -119,6 +119,8 @@ bool DiagnosticsEngine::popMappings(SourceLocation Loc) {
   return true;
 }
 
+void DiagnosticsEngine::ResetPragmas() { DiagStatesByLoc.clear(/*Soft=*/true); }
+
 void DiagnosticsEngine::Reset(bool soft /*=false*/) {
   ErrorOccurred = false;
   UncompilableErrorOccurred = false;
@@ -135,7 +137,7 @@ void DiagnosticsEngine::Reset(bool soft /*=false*/) {
   if (!soft) {
     // Clear state related to #pragma diagnostic.
     DiagStates.clear();
-    DiagStatesByLoc.clear();
+    DiagStatesByLoc.clear(false);
     DiagStateOnPushStack.clear();
 
     // Create a DiagState and DiagStatePoint representing diagnostic changes
diff --git a/clang/lib/Basic/SourceManager.cpp b/clang/lib/Basic/SourceManager.cpp
index 09e5c6547fb51..053e82683a4a6 100644
--- a/clang/lib/Basic/SourceManager.cpp
+++ b/clang/lib/Basic/SourceManager.cpp
@@ -344,6 +344,9 @@ void SourceManager::clearIDTables() {
   NextLocalOffset = 0;
   CurrentLoadedOffset = MaxLoadedOffset;
   createExpansionLoc(SourceLocation(), SourceLocation(), SourceLocation(), 1);
+  // Diagnostics engine keeps some references to fileids, mostly for dealing
+  // with diagnostic pragmas, make sure they're reset as well.
+  Diag.ResetPragmas();
 }
 
 bool SourceManager::isMainFile(const FileEntry &SourceFile) {
diff --git a/clang/unittests/Frontend/CompilerInstanceTest.cpp b/clang/unittests/Frontend/CompilerInstanceTest.cpp
index a7b258d5e537e..459a3864887e1 100644
--- a/clang/unittests/Frontend/CompilerInstanceTest.cpp
+++ b/clang/unittests/Frontend/CompilerInstanceTest.cpp
@@ -9,9 +9,12 @@
 #include "clang/Frontend/CompilerInstance.h"
 #include "clang/Basic/FileManager.h"
 #include "clang/Frontend/CompilerInvocation.h"
+#include "clang/Frontend/FrontendActions.h"
 #include "clang/Frontend/TextDiagnosticPrinter.h"
+#include "llvm/ADT/IntrusiveRefCntPtr.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/Format.h"
+#include "llvm/Support/MemoryBuffer.h"
 #include "llvm/Support/ToolOutputFile.h"
 #include "llvm/Support/VirtualFileSystem.h"
 #include "gtest/gtest.h"
@@ -97,4 +100,52 @@ TEST(CompilerInstance, AllowDiagnosticLogWithUnownedDiagnosticConsumer) {
   ASSERT_EQ(DiagnosticOutput, "error: expected no crash\n");
 }
 
+TEST(CompilerInstance, MultipleInputsCleansFileIDs) {
+  auto VFS = makeIntrusiveRefCnt<llvm::vfs::InMemoryFileSystem>();
+  VFS->addFile("a.cc", /*ModificationTime=*/{},
+               MemoryBuffer::getMemBuffer(R"cpp(
+      #include "a.h"
+      )cpp"));
+  // Paddings of `void foo();` in the sources below are "important". We're
+  // testing against source locations from previous compilations colliding.
+  // Hence the `unused` variable in `b.h` needs to be within `#pragma clang
+  // diagnostic` block from `a.h`.
+  VFS->addFile("a.h", /*ModificationTime=*/{}, MemoryBuffer::getMemBuffer(R"cpp(
+      #include "b.h"
+      #pragma clang diagnostic push
+      #pragma clang diagnostic warning "-Wunused"
+      void foo();
+      #pragma clang diagnostic pop
+      )cpp"));
+  VFS->addFile("b.h", /*ModificationTime=*/{}, MemoryBuffer::getMemBuffer(R"cpp(
+      void foo(); void foo(); void foo(); void foo();
+      inline void foo() { int unused = 2; }
+      )cpp"));
+
+  DiagnosticOptions DiagOpts;
+  IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
+      CompilerInstance::createDiagnostics(*VFS, DiagOpts);
+
+  CreateInvocationOptions CIOpts;
+  CIOpts.Diags = Diags;
+
+  const char *Args[] = {"clang", "-xc++", "a.cc"};
+  std::shared_ptr<CompilerInvocation> CInvok =
+      createInvocation(Args, std::move(CIOpts));
+  ASSERT_TRUE(CInvok) << "could not create compiler invocation";
+
+  CompilerInstance Instance(std::move(CInvok));
+  Instance.setDiagnostics(Diags.get());
+  Instance.createFileManager(VFS);
+
+  // Run once for `a.cc` and then for `a.h`. This makes sure we get the same
+  // file ID for `b.h` in the second run as `a.h` from first run.
+  const auto &OrigInputKind = Instance.getFrontendOpts().Inputs[0].getKind();
+  Instance.getFrontendOpts().Inputs.emplace_back("a.h", OrigInputKind);
+
+  SyntaxOnlyAction Act;
+  EXPECT_TRUE(Instance.ExecuteAction(Act)) << "Failed to execute action";
+  EXPECT_FALSE(Diags->hasErrorOccurred());
+  EXPECT_EQ(Diags->getNumWarnings(), 0u);
+}
 } // anonymous namespace

@kadircet kadircet requested a review from AaronBallman June 11, 2025 12:36
Copy link
Collaborator

@AaronBallman AaronBallman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@kadircet kadircet merged commit 4551e50 into llvm:main Jun 12, 2025
10 checks passed
@kadircet kadircet deleted the no_dangling_fids branch June 12, 2025 08:49
@llvm-ci
Copy link
Collaborator

llvm-ci commented Jun 12, 2025

LLVM Buildbot has detected a new failure on builder ppc64le-flang-rhel-clang running on ppc64le-flang-rhel-test while building clang at step 6 "test-build-unified-tree-check-flang".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/157/builds/30582

Here is the relevant piece of the build log for the reference
Step 6 (test-build-unified-tree-check-flang) failure: test (failure)
******************** TEST 'Flang :: Semantics/modfile75.F90' FAILED ********************
Exit Code: 2

Command Output (stderr):
--
/home/buildbots/llvm-external-buildbots/workers/ppc64le-flang-rhel-test/ppc64le-flang-rhel-clang-build/build/bin/flang -c -fhermetic-module-files -DWHICH=1 /home/buildbots/llvm-external-buildbots/workers/ppc64le-flang-rhel-test/ppc64le-flang-rhel-clang-build/llvm-project/flang/test/Semantics/modfile75.F90 && /home/buildbots/llvm-external-buildbots/workers/ppc64le-flang-rhel-test/ppc64le-flang-rhel-clang-build/build/bin/flang -c -fhermetic-module-files -DWHICH=2 /home/buildbots/llvm-external-buildbots/workers/ppc64le-flang-rhel-test/ppc64le-flang-rhel-clang-build/llvm-project/flang/test/Semantics/modfile75.F90 && /home/buildbots/llvm-external-buildbots/workers/ppc64le-flang-rhel-test/ppc64le-flang-rhel-clang-build/build/bin/flang -fc1 -fdebug-unparse /home/buildbots/llvm-external-buildbots/workers/ppc64le-flang-rhel-test/ppc64le-flang-rhel-clang-build/llvm-project/flang/test/Semantics/modfile75.F90 | /home/buildbots/llvm-external-buildbots/workers/ppc64le-flang-rhel-test/ppc64le-flang-rhel-clang-build/build/bin/FileCheck /home/buildbots/llvm-external-buildbots/workers/ppc64le-flang-rhel-test/ppc64le-flang-rhel-clang-build/llvm-project/flang/test/Semantics/modfile75.F90 # RUN: at line 1
+ /home/buildbots/llvm-external-buildbots/workers/ppc64le-flang-rhel-test/ppc64le-flang-rhel-clang-build/build/bin/flang -c -fhermetic-module-files -DWHICH=1 /home/buildbots/llvm-external-buildbots/workers/ppc64le-flang-rhel-test/ppc64le-flang-rhel-clang-build/llvm-project/flang/test/Semantics/modfile75.F90
+ /home/buildbots/llvm-external-buildbots/workers/ppc64le-flang-rhel-test/ppc64le-flang-rhel-clang-build/build/bin/flang -c -fhermetic-module-files -DWHICH=2 /home/buildbots/llvm-external-buildbots/workers/ppc64le-flang-rhel-test/ppc64le-flang-rhel-clang-build/llvm-project/flang/test/Semantics/modfile75.F90
+ /home/buildbots/llvm-external-buildbots/workers/ppc64le-flang-rhel-test/ppc64le-flang-rhel-clang-build/build/bin/flang -fc1 -fdebug-unparse /home/buildbots/llvm-external-buildbots/workers/ppc64le-flang-rhel-test/ppc64le-flang-rhel-clang-build/llvm-project/flang/test/Semantics/modfile75.F90
+ /home/buildbots/llvm-external-buildbots/workers/ppc64le-flang-rhel-test/ppc64le-flang-rhel-clang-build/build/bin/FileCheck /home/buildbots/llvm-external-buildbots/workers/ppc64le-flang-rhel-test/ppc64le-flang-rhel-clang-build/llvm-project/flang/test/Semantics/modfile75.F90
error: Semantic errors in /home/buildbots/llvm-external-buildbots/workers/ppc64le-flang-rhel-test/ppc64le-flang-rhel-clang-build/llvm-project/flang/test/Semantics/modfile75.F90
/home/buildbots/llvm-external-buildbots/workers/ppc64le-flang-rhel-test/ppc64le-flang-rhel-clang-build/llvm-project/flang/test/Semantics/modfile75.F90:15:11: error: Must be a constant value
    integer(c_int) n
            ^^^^^
FileCheck error: '<stdin>' is empty.
FileCheck command line:  /home/buildbots/llvm-external-buildbots/workers/ppc64le-flang-rhel-test/ppc64le-flang-rhel-clang-build/build/bin/FileCheck /home/buildbots/llvm-external-buildbots/workers/ppc64le-flang-rhel-test/ppc64le-flang-rhel-clang-build/llvm-project/flang/test/Semantics/modfile75.F90

--

********************


@nathanchance
Copy link
Member

FWIW, I am seeing an assertion failure when running check-clang after this change.

$ cmake \
      -B build \
      -G Ninja \
      -S llvm \
      -Wno-dev \
      -DCLANG_ENABLE_STATIC_ANALYZER=OFF \
      -DCLANG_PLUGIN_SUPPORT=OFF \
      -DCMAKE_BUILD_TYPE=Release \
      -DCMAKE_CXX_COMPILER=clang++ \
      -DCMAKE_C_COMPILER=clang \
      -DLLVM_ENABLE_ASSERTIONS=ON \
      -DLLVM_ENABLE_BINDINGS=OFF \
      -DLLVM_ENABLE_LIBXML2=OFF \
      -DLLVM_ENABLE_OCAMLDOC=OFF \
      -DLLVM_ENABLE_PROJECTS=clang \
      -DLLVM_ENABLE_WARNINGS=OFF \
      -DLLVM_EXTERNAL_CLANG_TOOLS_EXTRA_SOURCE_DIR= \
      -DLLVM_INCLUDE_DOCS=OFF \
      -DLLVM_INCLUDE_EXAMPLES=OFF \
      -DLLVM_USE_LINKER=lld
  and ninja -C build check-clang
...
FAIL: Clang-Unit :: ./AllClangUnitTests/179/182 (1868 of 21849)
******************** TEST 'Clang-Unit :: ./AllClangUnitTests/179/182' FAILED ********************
Script(shard):
--
GTEST_OUTPUT=json:.../llvm-project/build/tools/clang/unittests/./AllClangUnitTests-Clang-Unit-3404917-179-182.json GTEST_SHUFFLE=0 GTEST_TOTAL_SHARDS=182 GTEST_SHARD_INDEX=179 .../llvm-project/build/tools/clang/unittests/./AllClangUnitTests
--

Note: This is test shard 180 of 182.
[==========] Running 127 tests from 32 test suites.
[----------] Global test environment set-up.
[----------] 1 test from ToolChainTest
[ RUN      ] ToolChainTest.GetTargetAndMode
[       OK ] ToolChainTest.GetTargetAndMode (0 ms)
[----------] 1 test from ToolChainTest (0 ms total)

[----------] 1 test from HasAnyParameter
[ RUN      ] HasAnyParameter.MatchesIndependentlyOfPosition
[       OK ] HasAnyParameter.MatchesIndependentlyOfPosition (8 ms)
[----------] 1 test from HasAnyParameter (8 ms total)

[----------] 1 test from HasTemplateArgumentLoc
[ RUN      ] HasTemplateArgumentLoc.BindsToSpecializationWithDoubleArgument
[       OK ] HasTemplateArgumentLoc.BindsToSpecializationWithDoubleArgument (1 ms)
[----------] 1 test from HasTemplateArgumentLoc (1 ms total)

[----------] 1 test from CommentLexerTest
[ RUN      ] CommentLexerTest.HTML20
[       OK ] CommentLexerTest.HTML20 (0 ms)
[----------] 1 test from CommentLexerTest (0 ms total)

[----------] 1 test from DeclPrinter
[ RUN      ] DeclPrinter.TestVarDecl3
[       OK ] DeclPrinter.TestVarDecl3 (1 ms)
[----------] 1 test from DeclPrinter (1 ms total)

[----------] 1 test from FriendDecl
[ RUN      ] FriendDecl.FriendDecltypeRange
[       OK ] FriendDecl.FriendDecltypeRange (1 ms)
[----------] 1 test from FriendDecl (1 ms total)

[----------] 1 test from StructuralEquivalenceTemplateTest
[ RUN      ] StructuralEquivalenceTemplateTest.ExplicitBoolDifference
[       OK ] StructuralEquivalenceTemplateTest.ExplicitBoolDifference (4 ms)
[----------] 1 test from StructuralEquivalenceTemplateTest (4 ms total)

[----------] 1 test from InterpolateTest
[ RUN      ] InterpolateTest.Aliasing
[       OK ] InterpolateTest.Aliasing (0 ms)
[----------] 1 test from InterpolateTest (0 ms total)

[----------] 1 test from RecursiveASTVisitor
[ RUN      ] RecursiveASTVisitor.VisitsCallInNestedFunctionTemplateInstantiation
[       OK ] RecursiveASTVisitor.VisitsCallInNestedFunctionTemplateInstantiation (1 ms)
[----------] 1 test from RecursiveASTVisitor (1 ms total)

[----------] 1 test from Rewriter
[ RUN      ] Rewriter.ReplaceTextRangeTypes
[       OK ] Rewriter.ReplaceTextRangeTypes (1 ms)
[----------] 1 test from Rewriter (1 ms total)

[----------] 1 test from ClangToolTest
[ RUN      ] ClangToolTest.StripDependencyFileAdjusterMsvc
warning: unable to find a Visual Studio installation; try running Clang from a developer command prompt [-Wmsvc-not-found]
warning: argument unused during compilation: '-MP' [-Wunused-command-line-argument]
[       OK ] ClangToolTest.StripDependencyFileAdjusterMsvc (1 ms)
[----------] 1 test from ClangToolTest (1 ms total)

[----------] 1 test from CodeGenTest
[ RUN      ] CodeGenTest.TestNonAlterTest
AllClangUnitTests: .../llvm-project/llvm/lib/CodeGen/CodeGenTargetMachineImpl.cpp:48: void llvm::CodeGenTargetMachineImpl::initAsmInfo(): Assertion `MRI && "Unable to create reg info"' failed.
 #0 0x00005588c3b92598 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (.../llvm-project/build/tools/clang/unittests/./AllClangUnitTests+0x5f0b598)
 #1 0x00005588c3b901fc llvm::sys::RunSignalHandlers() (.../llvm-project/build/tools/clang/unittests/./AllClangUnitTests+0x5f091fc)
 #2 0x00005588c3b92dc1 SignalHandler(int, siginfo_t*, void*) Signals.cpp:0:0
 #3 0x00007fc9e1c4def0 (/usr/lib/libc.so.6+0x3def0)
 #4 0x00007fc9e1ca774c (/usr/lib/libc.so.6+0x9774c)
 #5 0x00007fc9e1c4ddc0 raise (/usr/lib/libc.so.6+0x3ddc0)
 #6 0x00007fc9e1c3557a abort (/usr/lib/libc.so.6+0x2557a)
 #7 0x00007fc9e1c354e3 __assert_perror_fail (/usr/lib/libc.so.6+0x254e3)
 #8 0x00005588c7fc9e04 llvm::CodeGenTargetMachineImpl::initAsmInfo() (.../llvm-project/build/tools/clang/unittests/./AllClangUnitTests+0xa342e04)
 #9 0x00005588c5009df6 llvm::X86TargetMachine::X86TargetMachine(llvm::Target const&, llvm::Triple const&, llvm::StringRef, llvm::StringRef, llvm::TargetOptions const&, std::optional<llvm::Reloc::Model>, std::optional<llvm::CodeModel::Model>, llvm::CodeGenOptLevel, bool) X86TargetMachine.cpp:0:0
#10 0x00005588c500b704 llvm::RegisterTargetMachine<llvm::X86TargetMachine>::Allocator(llvm::Target const&, llvm::Triple const&, llvm::StringRef, llvm::StringRef, llvm::TargetOptions const&, std::optional<llvm::Reloc::Model>, std::optional<llvm::CodeModel::Model>, llvm::CodeGenOptLevel, bool) X86TargetMachine.cpp:0:0
#11 0x00005588c75cbecf clang::emitBackendOutput(clang::CompilerInstance&, clang::CodeGenOptions&, llvm::StringRef, llvm::Module*, clang::BackendAction, llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem>, std::unique_ptr<llvm::raw_pwrite_stream, std::default_delete<llvm::raw_pwrite_stream>>, clang::BackendConsumer*) (.../llvm-project/build/tools/clang/unittests/./AllClangUnitTests+0x9944ecf)
#12 0x00005588c75c2e43 clang::BackendConsumer::HandleTranslationUnit(clang::ASTContext&) (.../llvm-project/build/tools/clang/unittests/./AllClangUnitTests+0x993be43)
#13 0x00005588c6dc172c clang::MultiplexConsumer::HandleTranslationUnit(clang::ASTContext&) (.../llvm-project/build/tools/clang/unittests/./AllClangUnitTests+0x913a72c)
#14 0x00005588c6046489 clang::ParseAST(clang::Sema&, bool, bool) (.../llvm-project/build/tools/clang/unittests/./AllClangUnitTests+0x83bf489)
#15 0x00005588c6d29226 clang::FrontendAction::Execute() (.../llvm-project/build/tools/clang/unittests/./AllClangUnitTests+0x90a2226)
#16 0x00005588c6c97fdd clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) (.../llvm-project/build/tools/clang/unittests/./AllClangUnitTests+0x9010fdd)
#17 0x00005588c6ffad7a clang::tooling::FrontendActionFactory::runInvocation(std::shared_ptr<clang::CompilerInvocation>, clang::FileManager*, std::shared_ptr<clang::PCHContainerOperations>, clang::DiagnosticConsumer*) (.../llvm-project/build/tools/clang/unittests/./AllClangUnitTests+0x9373d7a)
#18 0x00005588c6ffaaba clang::tooling::ToolInvocation::runInvocation(char const*, clang::driver::Compilation*, std::shared_ptr<clang::CompilerInvocation>, std::shared_ptr<clang::PCHContainerOperations>) (.../llvm-project/build/tools/clang/unittests/./AllClangUnitTests+0x9373aba)
#19 0x00005588c6ff9435 clang::tooling::ToolInvocation::run() (.../llvm-project/build/tools/clang/unittests/./AllClangUnitTests+0x9372435)
#20 0x00005588c6ff8c90 clang::tooling::runToolOnCodeWithArgs(std::unique_ptr<clang::FrontendAction, std::default_delete<clang::FrontendAction>>, llvm::Twine const&, llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem>, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>> const&, llvm::Twine const&, llvm::Twine const&, std::shared_ptr<clang::PCHContainerOperations>) (.../llvm-project/build/tools/clang/unittests/./AllClangUnitTests+0x9371c90)
#21 0x00005588c6ff8825 clang::tooling::runToolOnCodeWithArgs(std::unique_ptr<clang::FrontendAction, std::default_delete<clang::FrontendAction>>, llvm::Twine const&, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>> const&, llvm::Twine const&, llvm::Twine const&, std::shared_ptr<clang::PCHContainerOperations>, std::vector<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>>> const&) (.../llvm-project/build/tools/clang/unittests/./AllClangUnitTests+0x9371825)
#22 0x00005588c39ceeb3 (anonymous namespace)::CodeGenTest_TestNonAlterTest_Test::TestBody() NoAlterCodeGenActionTest.cpp:0:0
#23 0x00005588c56a0fb0 testing::Test::Run() (.../llvm-project/build/tools/clang/unittests/./AllClangUnitTests+0x7a19fb0)
#24 0x00005588c56a24c0 testing::TestInfo::Run() (.../llvm-project/build/tools/clang/unittests/./AllClangUnitTests+0x7a1b4c0)
#25 0x00005588c56a30df testing::TestSuite::Run() (.../llvm-project/build/tools/clang/unittests/./AllClangUnitTests+0x7a1c0df)
#26 0x00005588c56b3dc4 testing::internal::UnitTestImpl::RunAllTests() (.../llvm-project/build/tools/clang/unittests/./AllClangUnitTests+0x7a2cdc4)
#27 0x00005588c56b31b9 testing::UnitTest::Run() (.../llvm-project/build/tools/clang/unittests/./AllClangUnitTests+0x7a2c1b9)
#28 0x00005588c568baac main (.../llvm-project/build/tools/clang/unittests/./AllClangUnitTests+0x7a04aac)
#29 0x00007fc9e1c376b5 (/usr/lib/libc.so.6+0x276b5)
#30 0x00007fc9e1c37769 __libc_start_main (/usr/lib/libc.so.6+0x27769)
#31 0x00005588c2b218a5 _start (.../llvm-project/build/tools/clang/unittests/./AllClangUnitTests+0x4e9a8a5)

--
exit: -6
--
shard JSON output does not exist: .../llvm-project/build/tools/clang/unittests/./AllClangUnitTests-Clang-Unit-3404917-179-182.json
********************
********************
Failed Tests (1):
  Clang-Unit :: ./AllClangUnitTests/179/182


Testing Time: 61.64s

Total Discovered Tests: 45779
  Skipped          :     1 (0.00%)
  Unsupported      :  1441 (3.15%)
  Passed           : 44312 (96.80%)
  Expectedly Failed:    24 (0.05%)
  Failed           :     1 (0.00%)
# bad: [2ee8fdbfddcca86ac079104718e6fda3aabed0eb] [libc] Prevent building wchar on MacOS (#143978)
# good: [02550da932913bd7c3987c68abc9060c9e5bde2c] [OpenMP 60] Initial parsing/sema for `need_device_addr` modifier on `adjust_args` clause (#143442)
git bisect start '2ee8fdbfddcca86ac079104718e6fda3aabed0eb' '02550da932913bd7c3987c68abc9060c9e5bde2c'
# bad: [e4de74ba11eadb47cf78afbabffbf2b1a50e7298] [mlir][Vector] Tighten up application conditions in TransferReadAfter… (#143869)
git bisect bad e4de74ba11eadb47cf78afbabffbf2b1a50e7298
# bad: [013034cd0f5ae19ef02fc35a83362874e727f13c] Follow-up to 97ac6483aae, squelch an unused lambda capture warning
git bisect bad 013034cd0f5ae19ef02fc35a83362874e727f13c
# bad: [4551e5035565606eb04253a35f31d51685657436] [clang] Reset FileID based diag state mappings (#143695)
git bisect bad 4551e5035565606eb04253a35f31d51685657436
# good: [6157028fea93ff14af18b173dd01eb431cfb6aef] [BasicAA][ValueTracking] Increase depth for underlying object search (#143714)
git bisect good 6157028fea93ff14af18b173dd01eb431cfb6aef
# good: [edaac11df3f82268e8ca34bf34b3e9d115b7d475] [X86] combineSelect - attempt to combine with shuffles (#143753)
git bisect good edaac11df3f82268e8ca34bf34b3e9d115b7d475
# good: [5434b85d2c7a83d9cebae06dad2f9d630e9a3927] ARM: Remove fake entries for divrem libcalls (#143832)
git bisect good 5434b85d2c7a83d9cebae06dad2f9d630e9a3927
# good: [ce621041c2f162c50d630810491c2feee8eb6c64] [RISCV] Get host CPU name via hwprobe (#142745)
git bisect good ce621041c2f162c50d630810491c2feee8eb6c64
# first bad commit: [4551e5035565606eb04253a35f31d51685657436] [clang] Reset FileID based diag state mappings (#143695)

@kadircet
Copy link
Member Author

hi @nathanchance, I can't seem to reproduce the failure, and I couldn't find any buildbots with this failure (also the assertion you're seeing conceptually shouldn't be triggered by state in diagnostics engine). I am not sure how to proceed here but can you at least verify if the issue is not specific to your environment and reproduces elsewhere?

@kadircet
Copy link
Member Author

ok so I did a little more investigation here, and tl;dr is:

  • LLVM's target registry mechanism relies on static initialization of variables by the main driver program (usually clang driver takes care of this for real world runs).
  • There are some tests (especially the ones that make use of CodeGenAction) that'll succeed when no targets are registered, or when all targets are registered properly, but would fail when targets are registered partially (i.e. we know the target infos, but we don't know target mcs).
  • Because these registries are shared across the process, behavior being tested starts to rely on test execution order (as some tests end up registering these targets).
  • There's a very good chance execution order gets shuffled with every commit that introduces a clang unit test, since db2315a. We basically have a single process for all the unit tests now, whereas these interactions were limited to ~per unit-test directory before (still problematic before that change, but issues were localized and less likely to change at every commit).
  • These types of failures were also addressed in the commit mentioned above.

going to mention this in the original commit to see what authors think.

tomtor pushed a commit to tomtor/llvm-project that referenced this pull request Jun 14, 2025
When sharing same compiler instance for multiple compilations, we reset
source manager's file id tables in between runs. Diagnostics engine
keeps a cache based on these file ids, that became dangling references
across compilations.

This patch makes sure we reset those whenever sourcemanager is trashing
its FileIDs.
@rnk
Copy link
Collaborator

rnk commented Jun 16, 2025

I came up with this:
#144428

Registering just the targets without the MC info causes the CodeGenTests to fail deterministically because they can't produce assembly, as you mention in other comments.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:frontend Language frontend issues, e.g. anything involving "Sema" clang Clang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants