diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index 7f666a46077a..87b5296c9460 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -3648,7 +3648,8 @@ void ASTDeclReader::UpdateDecl(Decl *D, ModuleFile &ModuleFile, auto *RD = cast(D); auto *OldDD = RD->DefinitionData.getNotUpdated(); bool HadRealDefinition = - OldDD && !Reader.PendingFakeDefinitionData.count(OldDD); + OldDD && (OldDD->Definition != RD || + !Reader.PendingFakeDefinitionData.count(OldDD)); ReadCXXRecordDefinition(RD, /*Update*/true); // Visible update is handled separately. diff --git a/clang/test/Modules/Inputs/merge-template-members/a.h b/clang/test/Modules/Inputs/merge-template-members/a1.h similarity index 100% rename from clang/test/Modules/Inputs/merge-template-members/a.h rename to clang/test/Modules/Inputs/merge-template-members/a1.h diff --git a/clang/test/Modules/Inputs/merge-template-members/a2.h b/clang/test/Modules/Inputs/merge-template-members/a2.h new file mode 100644 index 000000000000..9212a3f0debc --- /dev/null +++ b/clang/test/Modules/Inputs/merge-template-members/a2.h @@ -0,0 +1,9 @@ +namespace N { + template struct A { + int n; + A() : n() {} + }; + + // Create declaration of A. + typedef A AI; +} diff --git a/clang/test/Modules/Inputs/merge-template-members/b.h b/clang/test/Modules/Inputs/merge-template-members/b.h deleted file mode 100644 index df537b0d59d8..000000000000 --- a/clang/test/Modules/Inputs/merge-template-members/b.h +++ /dev/null @@ -1,6 +0,0 @@ -#include "a.h" - -// Add update record for definition of A and constructors. -// We need an eagerly-emitted function here to get the problematic -// deserialization ordering. -void foobar() { N::A x; } diff --git a/clang/test/Modules/Inputs/merge-template-members/b1.h b/clang/test/Modules/Inputs/merge-template-members/b1.h new file mode 100644 index 000000000000..3828e267edde --- /dev/null +++ b/clang/test/Modules/Inputs/merge-template-members/b1.h @@ -0,0 +1,6 @@ +#include "a1.h" + +// Add update record for definition of A and constructors. +// We need an eagerly-emitted use here to get the problematic +// deserialization ordering. +N::A b1; diff --git a/clang/test/Modules/Inputs/merge-template-members/b2.h b/clang/test/Modules/Inputs/merge-template-members/b2.h new file mode 100644 index 000000000000..37357acc6adf --- /dev/null +++ b/clang/test/Modules/Inputs/merge-template-members/b2.h @@ -0,0 +1,6 @@ +#include "a2.h" + +// Add update record for definition of A and constructors. +// We need an eagerly-emitted use here to get the problematic +// deserialization ordering. +N::A b2; diff --git a/clang/test/Modules/Inputs/merge-template-members/c.h b/clang/test/Modules/Inputs/merge-template-members/c.h index 54f34799c397..92f20a0b1329 100644 --- a/clang/test/Modules/Inputs/merge-template-members/c.h +++ b/clang/test/Modules/Inputs/merge-template-members/c.h @@ -11,4 +11,4 @@ namespace N { } // Merge in another declaration and update records. -#include "b.h" +#include "b1.h" diff --git a/clang/test/Modules/Inputs/merge-template-members/module.modulemap b/clang/test/Modules/Inputs/merge-template-members/module.modulemap index 280667fcd79d..0d72e58fbf1b 100644 --- a/clang/test/Modules/Inputs/merge-template-members/module.modulemap +++ b/clang/test/Modules/Inputs/merge-template-members/module.modulemap @@ -1,6 +1,9 @@ module def { header "def.h" export * } module update { header "update.h" export * } -module a { header "a.h" export * } -module b { header "b.h" export * } +module a1 { header "a1.h" export * } +module a2 { header "a2.h" export * } +module b1 { header "b1.h" export * } +module b2 { header "b2.h" export * } +module merge { header "merge.h" export * } module c { header "c.h" export * } diff --git a/clang/test/Modules/merge-template-members.cpp b/clang/test/Modules/merge-template-members.cpp index c0bfd2f22bb9..1fdaa9c29be2 100644 --- a/clang/test/Modules/merge-template-members.cpp +++ b/clang/test/Modules/merge-template-members.cpp @@ -1,9 +1,10 @@ // RUN: rm -rf %t -// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I%S/Inputs/merge-template-members -verify -emit-llvm-only %s +// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I%S/Inputs/merge-template-members -verify -emit-llvm-only %s -DTEST=1 +// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I%S/Inputs/merge-template-members -verify -emit-llvm-only %s -DTEST=2 +// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I%S/Inputs/merge-template-members -verify -emit-llvm-only %s -DTEST=3 // expected-no-diagnostics -#include "c.h" -N::A ai; +#if TEST == 1 template struct A { int n; }; template struct B { typedef A C; }; @@ -11,3 +12,16 @@ template class B; #include "update.h" B::C use2; + +#elif TEST == 2 + +#include "c.h" +N::A ai; + +#elif TEST == 3 + +#include "merge.h" + +#else +#error Unknown test +#endif