Skip to content

Conversation

@alanzhao1
Copy link
Contributor

ASTReader::FinishedDeserializing() calls
adjustDeductedFunctionResultType(...) 0, which in turn calls FunctionDecl::getMostRecentDecl()1. In modules builds, getMostRecentDecl() may reach out to the ASTReader and start deserializing again. Starting deserialization starts ReadTimer; however, FinishedDeserializing() doesn't call stopTimer() until after it's call to adjustDeductedFunctionResultType(...) 2. As a result, we hit an assert checking that we don't start an already started timer 3. To fix this, we simply don't start the timer if it's already running.

Unfortunately I don't have a test case for this yet as modules builds are notoriously difficult to reduce.

`ASTReader::FinishedDeserializing()` calls
`adjustDeductedFunctionResultType(...)` [0], which in turn calls
`FunctionDecl::getMostRecentDecl()`[1]. In modules builds,
`getMostRecentDecl()` may reach out to the `ASTReader` and start
deserializing again. Starting deserialization starts `ReadTimer`;
however, `FinishedDeserializing()` doesn't call `stopTimer()` until
after it's call to `adjustDeductedFunctionResultType(...)` [2]. As a
result, we hit an assert checking that we don't start an already started
timer [3]. To fix this, we simply don't start the timer if it's already
running.

Unfortunately I don't have a test case for this yet as modules builds
are notoriously difficult to reduce.

[0]: https://github.com/llvm/llvm-project/blob/4d2288d31866013bd361800df4746fbc2fcf742a/clang/lib/Serialization/ASTReader.cpp#L11053
[1]: https://github.com/llvm/llvm-project/blob/4d2288d31866013bd361800df4746fbc2fcf742a/clang/lib/AST/ASTContext.cpp#L3804
[2]: https://github.com/llvm/llvm-project/blob/4d2288d31866013bd361800df4746fbc2fcf742a/clang/lib/Serialization/ASTReader.cpp#L11065-L11066
[3]: https://github.com/llvm/llvm-project/blob/4d2288d31866013bd361800df4746fbc2fcf742a/llvm/lib/Support/Timer.cpp#L150
@llvmbot llvmbot added clang Clang issues not falling into any other category clang:modules C++20 modules and Clang Header Modules labels Aug 19, 2025
@llvmbot
Copy link
Member

llvmbot commented Aug 19, 2025

@llvm/pr-subscribers-clang

@llvm/pr-subscribers-clang-modules

Author: Alan Zhao (alanzhao1)

Changes

ASTReader::FinishedDeserializing() calls
adjustDeductedFunctionResultType(...) 0, which in turn calls FunctionDecl::getMostRecentDecl()1. In modules builds, getMostRecentDecl() may reach out to the ASTReader and start deserializing again. Starting deserialization starts ReadTimer; however, FinishedDeserializing() doesn't call stopTimer() until after it's call to adjustDeductedFunctionResultType(...) 2. As a result, we hit an assert checking that we don't start an already started timer 3. To fix this, we simply don't start the timer if it's already running.

Unfortunately I don't have a test case for this yet as modules builds are notoriously difficult to reduce.


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

1 Files Affected:

  • (modified) clang/lib/Serialization/ASTReader.cpp (+2-1)
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index e8dddda584a9b..bff289f1c1b76 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -11003,7 +11003,8 @@ void ASTReader::diagnoseOdrViolations() {
 }
 
 void ASTReader::StartedDeserializing() {
-  if (++NumCurrentElementsDeserializing == 1 && ReadTimer.get())
+  if (Timer *T = ReadTimer.get();
+      ++NumCurrentElementsDeserializing == 1 && T && !T->isRunning())
     ReadTimer->startTimer();
 }
 

Copy link
Contributor

@ilya-biryukov ilya-biryukov left a comment

Choose a reason for hiding this comment

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

LGTM! Thanks for trying the alternative approach and confirming it is not as easy as I anticipated.

The change solves a real assertion failure we saw in our codebase and is an improvement, thanks a lot!

See the rationale for the stylistic comment I made too. Happy for you to go either way on it, don't feel compelled to address it before landing if you disagree.

@alanzhao1 alanzhao1 enabled auto-merge (squash) August 20, 2025 21:10
@alanzhao1 alanzhao1 merged commit 904b4f5 into llvm:main Aug 20, 2025
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

clang:modules C++20 modules and Clang Header Modules clang Clang issues not falling into any other category

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants