[clang] [PATCH] [clang][frontend] Fix AllocKind retrieving for `CXXConstructorDecl` refs #132794 (PR #133077)

Paul Schwabauer via cfe-commits cfe-commits at lists.llvm.org
Wed Mar 26 07:38:30 PDT 2025


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

>From 86033b4b698ad11cf358b929e950f0b01e50390e Mon Sep 17 00:00:00 2001
From: koplas <paul at 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>{};
+}



More information about the cfe-commits mailing list