3 Commits

Author SHA1 Message Date
Michael Park
0689d23ab3
[C++20][Modules] Prevent premature calls to PassInterestingDeclsToConsumer() within FinishedDeserializing(). (#129982)
`ASTReader::FinishedDeserializing` uses `NumCurrentElementsDeserializing` to keep track of nested `Deserializing` RAII actions. The `FinishedDeserializing` only performs actions if it is the top-level `Deserializing` layer. This works fine in general, but there is a problematic edge case.

If a call to `redecls()` in `FinishedDeserializing` performs deserialization, we re-enter `FinishedDeserializing` while in the middle of the previous `FinishedDeserializing` call.

The known problematic part of this is that this inner `FinishedDeserializing` can go all the way to `PassInterestingDeclsToConsumer`, which operates on `PotentiallyInterestingDecls` data structure which contain decls that should be handled by the previous `FinishedDeserializing` stage.

The other shared data structures are also somewhat concerning at a high-level in that the inner `FinishedDeserializing` would be handling pending actions that are not "within its scope", but this part is not known to be problematic.

We already have a guard within `PassInterestingDeclsToConsumer` because we can end up with recursive deserialization within `PassInterestingDeclsToConsumer`. The implemented solution is to apply this guard to the portion of `FinishedDeserializing` that performs further deserialization as well. This ensures that recursive deserialization does not trigger `PassInterestingDeclsToConsumer` which may operate on entries that are not ready to be passed.
2025-03-15 23:03:20 -07:00
Zixu Wang
912b154f3a
Revert "[C++20][Modules][Serialization] Delay marking pending incompl… (#127136)
…ete decl chains until the end of `finishPendingActions`. (#121245)"

This reverts commit a9e249f64e800fbb20a3b26c0cfb68c1a1aee5e1.

Reverting this change because of issue #126973.
2025-02-13 16:12:22 -08:00
Michael Park
a9e249f64e
[C++20][Modules][Serialization] Delay marking pending incomplete decl chains until the end of finishPendingActions. (#121245)
The call to `hasBody` inside `finishPendingActions` that bumps the `PendingIncompleteDeclChains`
size from `0` to `1`, and also sets the `LazyVal->LastGeneration` to `6` which matches
the `LazyVal->ExternalSource->getGeneration()` value of `6`. Later, the iterations over `redecls()`
(which calls `getNextRedeclaration`) is expected to trigger the reload, but it **does not** since
the generation numbers match.

The proposed solution is to perform the marking of incomplete decl chains at the end of `finishPendingActions`.
This way, **all** of the incomplete decls are marked incomplete as a post-condition of `finishPendingActions`.
It's also safe to delay this operation since any operation being done within `finishPendingActions` has
`NumCurrentElementsDeserializing == 1`, which means that any calls to `CompleteDeclChain` would simply
add to the `PendingIncompleteDeclChains` without doing anything anyway.
2025-02-03 11:22:02 -08:00