diff --git a/clang/include/clang/Serialization/ASTReader.h b/clang/include/clang/Serialization/ASTReader.h index 1360ee1877c1a..af01bacbfdc42 100644 --- a/clang/include/clang/Serialization/ASTReader.h +++ b/clang/include/clang/Serialization/ASTReader.h @@ -988,6 +988,9 @@ class ASTReader ///Whether we are currently processing update records. bool ProcessingUpdateRecords = false; + /// Whether we are going to write modules. + bool FinalizedForWriting = false; + using SwitchCaseMapTy = llvm::DenseMap; /// Mapping from switch-case IDs in the chain to switch-case statements diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index bdf476cf128a3..93409df3d4fc4 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -5089,7 +5089,8 @@ void ASTReader::InitializeContext() { } void ASTReader::finalizeForWriting() { - // Nothing to do for now. + assert(!NumCurrentElementsDeserializing && "deserializing when reading"); + FinalizedForWriting = true; } /// Reads and return the signature record from \p PCH's control block, or @@ -7328,6 +7329,12 @@ Decl *ASTReader::GetExternalDecl(uint32_t ID) { } void ASTReader::CompleteRedeclChain(const Decl *D) { + // We don't need to complete declaration chain after we start writing. + // We loses more chances to find ODR violation in the writing place and + // we get more efficient writing process. + if (FinalizedForWriting) + return; + if (NumCurrentElementsDeserializing) { // We arrange to not care about the complete redeclaration chain while we're // deserializing. Just remember that the AST has marked this one as complete diff --git a/clang/test/Modules/polluted-operator.cppm b/clang/test/Modules/polluted-operator.cppm index b24464aa6ad21..9b45734432db9 100644 --- a/clang/test/Modules/polluted-operator.cppm +++ b/clang/test/Modules/polluted-operator.cppm @@ -51,7 +51,20 @@ module; export module b; import a; +void b() { + std::variant v; +} + // expected-error@* {{has different definitions in different modules; first difference is defined here found data member '_S_copy_ctor' with an initializer}} // expected-note@* {{but in 'a.' found data member '_S_copy_ctor' with a different initializer}} // expected-error@* {{from module 'a.' is not present in definition of 'variant<_Types...>' provided earlier}} // expected-note@* {{declaration of 'swap' does not match}} + +//--- c.cppm +module; +#include "bar.h" +export module c; +import a; + +// expected-error@* {{has different definitions in different modules; first difference is defined here found data member '_S_copy_ctor' with an initializer}} +// expected-note@* {{but in 'a.' found data member '_S_copy_ctor' with a different initializer}}