Skip to content

Commit 86033b4

Browse files
committed
[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.
1 parent 23882f0 commit 86033b4

File tree

2 files changed

+48
-2
lines changed

2 files changed

+48
-2
lines changed

clang/include/clang/AST/DeclCXX.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2601,10 +2601,11 @@ class CXXConstructorDecl final
26012601
void anchor() override;
26022602

26032603
size_t numTrailingObjects(OverloadToken<InheritedConstructor>) const {
2604-
return CXXConstructorDeclBits.IsInheritingConstructor;
2604+
return getCanonicalDecl()->CXXConstructorDeclBits.IsInheritingConstructor;
26052605
}
26062606
size_t numTrailingObjects(OverloadToken<ExplicitSpecifier>) const {
2607-
return CXXConstructorDeclBits.HasTrailingExplicitSpecifier;
2607+
return getCanonicalDecl()
2608+
->CXXConstructorDeclBits.HasTrailingExplicitSpecifier;
26082609
}
26092610

26102611
ExplicitSpecifier getExplicitSpecifierInternal() const {
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
// Tests complex explicit constructor across modules.
2+
//
3+
// RUN: rm -rf %t
4+
// RUN: mkdir -p %t
5+
// RUN: split-file %s %t
6+
7+
// RUN: %clang_cc1 -std=c++20 -emit-module-interface %t/Foo.cppm \
8+
// RUN: -o %t/Foo.pcm
9+
10+
// RUN: %clang_cc1 -std=c++20 -emit-module-interface \
11+
// RUN: -fmodule-file=Foo=%t/Foo.pcm \
12+
// RUN: %t/Bar.cppm \
13+
// RUN: -o %t/Bar.pcm
14+
15+
// RUN: %clang_cc1 -std=c++20 -emit-obj \
16+
// RUN: -main-file-name Bar.cppm \
17+
// RUN: -fmodule-file=Foo=%t/Foo.pcm \
18+
// RUN: -x pcm %t/Bar.pcm \
19+
// RUN: -o %t/Bar.o
20+
21+
//--- Foo.cppm
22+
export module Foo;
23+
24+
export {
25+
template<class T>
26+
class Foo {
27+
public:
28+
template<class... Args>
29+
explicit (sizeof...(Args) == 1) Foo(Args&&... args);
30+
};
31+
}
32+
33+
template<class T>
34+
template<class... Args>
35+
inline Foo<T>::Foo(Args&&... args) {}
36+
37+
//--- Bar.cppm
38+
export module Bar;
39+
import Foo;
40+
41+
struct Bar {};
42+
43+
void a() {
44+
auto foo = Foo<Bar>{};
45+
}

0 commit comments

Comments
 (0)