From 81df4736822848b35959aa067fc9d056ed868946 Mon Sep 17 00:00:00 2001
From: koplas <paul@schwabauer.co>
Date: Thu, 27 Mar 2025 08:00:54 +0100
Subject: [PATCH 1/2] [PATCH] [clang][frontend] Fix serialization for
 CXXConstructorDecl (refs llvm#132794)

When retrieving the ExplicitSpecifier from a CXXConstructorDecl, one
of its canonical declarations is returned. To correctly write the
declaration record the ExplicitSpecifier of the current declaration
must be used.

Failing to do so results in a crash during deserialization.
---
 clang/docs/ReleaseNotes.rst                   |  1 +
 clang/lib/Serialization/ASTWriterDecl.cpp     |  2 +-
 .../test/Modules/ComplexExplicitSpecifier.cpp | 45 +++++++++++++++++++
 3 files changed, 47 insertions(+), 1 deletion(-)
 create mode 100644 clang/test/Modules/ComplexExplicitSpecifier.cpp

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 04ec2cfef679c..6acbe7131461c 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -316,6 +316,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. (GH#132794)
 
 Bug Fixes to Compiler Builtins
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/clang/lib/Serialization/ASTWriterDecl.cpp b/clang/lib/Serialization/ASTWriterDecl.cpp
index 7014d7d291a5d..a14b8cf201bba 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 0000000000000..33501ba264cc6
--- /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>{};
+}

From 2241ab9b21d6cf5e332978e5f7877d09fa3235b4 Mon Sep 17 00:00:00 2001
From: Paul Schwabauer <pschwabauer@intevation.de>
Date: Thu, 27 Mar 2025 10:49:04 +0100
Subject: [PATCH 2/2] Fix GitHub reference

Co-authored-by: cor3ntin <corentinjabot@gmail.com>
---
 clang/docs/ReleaseNotes.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 6acbe7131461c..af063901ed62d 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -316,7 +316,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. (GH#132794)
+- Fixed a modules crash where an explicit Constructor was deserialized. (#GH132794)
 
 Bug Fixes to Compiler Builtins
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^