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 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^