https://github.com/koplas updated 
https://github.com/llvm/llvm-project/pull/133077

>From 86033b4b698ad11cf358b929e950f0b01e50390e Mon Sep 17 00:00:00 2001
From: koplas <p...@schwabauer.co>
Date: Wed, 26 Mar 2025 13:49:44 +0100
Subject: [PATCH] [PATCH] [clang][frontend] Fix AllocKind retrieval for
 CXXConstructorDecl (refs #132794)

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

Failing to do so results in a crash during deserialization.
---
 clang/include/clang/AST/DeclCXX.h             |  5 ++-
 .../test/Modules/ComplexExplicitSpecifier.cpp | 45 +++++++++++++++++++
 2 files changed, 48 insertions(+), 2 deletions(-)
 create mode 100644 clang/test/Modules/ComplexExplicitSpecifier.cpp

diff --git a/clang/include/clang/AST/DeclCXX.h 
b/clang/include/clang/AST/DeclCXX.h
index dbd02ef7f8011..7728669b3bcec 100644
--- a/clang/include/clang/AST/DeclCXX.h
+++ b/clang/include/clang/AST/DeclCXX.h
@@ -2601,10 +2601,11 @@ class CXXConstructorDecl final
   void anchor() override;
 
   size_t numTrailingObjects(OverloadToken<InheritedConstructor>) const {
-    return CXXConstructorDeclBits.IsInheritingConstructor;
+    return getCanonicalDecl()->CXXConstructorDeclBits.IsInheritingConstructor;
   }
   size_t numTrailingObjects(OverloadToken<ExplicitSpecifier>) const {
-    return CXXConstructorDeclBits.HasTrailingExplicitSpecifier;
+    return getCanonicalDecl()
+        ->CXXConstructorDeclBits.HasTrailingExplicitSpecifier;
   }
 
   ExplicitSpecifier getExplicitSpecifierInternal() const {
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>{};
+}

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to