aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--clang/docs/ReleaseNotes.rst1
-rw-r--r--clang/lib/Serialization/ASTWriterDecl.cpp2
-rw-r--r--clang/test/Modules/ComplexExplicitSpecifier.cpp45
3 files changed, 47 insertions, 1 deletions
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index b96780c..eaecead 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -323,6 +323,7 @@ Bug Fixes in This Version
- Fixed a modules crash where exception specifications were not propagated properly (#GH121245, relanded in #GH129982)
- Fixed a problematic case with recursive deserialization within ``FinishedDeserializing()`` where
``PassInterestingDeclsToConsumer()`` was called before the declarations were safe to be passed. (#GH129982)
+- Fixed a modules crash where an explicit Constructor was deserialized. (#GH132794)
Bug Fixes to Compiler Builtins
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/clang/lib/Serialization/ASTWriterDecl.cpp b/clang/lib/Serialization/ASTWriterDecl.cpp
index 7014d7d..a14b8cf 100644
--- a/clang/lib/Serialization/ASTWriterDecl.cpp
+++ b/clang/lib/Serialization/ASTWriterDecl.cpp
@@ -1726,7 +1726,7 @@ void ASTDeclWriter::VisitCXXConstructorDecl(CXXConstructorDecl *D) {
"CXXConstructorDeclBits");
Record.push_back(D->getTrailingAllocKind());
- addExplicitSpecifier(D->getExplicitSpecifier(), Record);
+ addExplicitSpecifier(D->getExplicitSpecifierInternal(), Record);
if (auto Inherited = D->getInheritedConstructor()) {
Record.AddDeclRef(Inherited.getShadowDecl());
Record.AddDeclRef(Inherited.getConstructor());
diff --git a/clang/test/Modules/ComplexExplicitSpecifier.cpp b/clang/test/Modules/ComplexExplicitSpecifier.cpp
new file mode 100644
index 0000000..33501ba
--- /dev/null
+++ b/clang/test/Modules/ComplexExplicitSpecifier.cpp
@@ -0,0 +1,45 @@
+// Tests complex explicit constructor across modules.
+//
+// RUN: rm -rf %t
+// RUN: mkdir -p %t
+// RUN: split-file %s %t
+
+// RUN: %clang_cc1 -std=c++20 -emit-module-interface %t/Foo.cppm \
+// RUN: -o %t/Foo.pcm
+
+// RUN: %clang_cc1 -std=c++20 -emit-module-interface \
+// RUN: -fmodule-file=Foo=%t/Foo.pcm \
+// RUN: %t/Bar.cppm \
+// RUN: -o %t/Bar.pcm
+
+// RUN: %clang_cc1 -std=c++20 -emit-obj \
+// RUN: -main-file-name Bar.cppm \
+// RUN: -fmodule-file=Foo=%t/Foo.pcm \
+// RUN: -x pcm %t/Bar.pcm \
+// RUN: -o %t/Bar.o
+
+//--- Foo.cppm
+export module Foo;
+
+export {
+template<class T>
+class Foo {
+ public:
+ template<class... Args>
+ explicit (sizeof...(Args) == 1) Foo(Args&&... args);
+};
+}
+
+template<class T>
+template<class... Args>
+inline Foo<T>::Foo(Args&&... args) {}
+
+//--- Bar.cppm
+export module Bar;
+import Foo;
+
+struct Bar {};
+
+void a() {
+ auto foo = Foo<Bar>{};
+}