Skip to content

Commit 9f1e9f6

Browse files
authoredDec 12, 2024··
[C++20][modules] Fix std::initializer_list recognition if it's exported out of a module (#118537)
If the std::initializer_list is exported out of module, its `DeclContext` is not a namespace as `Sema::isStdInitializerList` expects, but an `Decl::Kind::Export` and only its parent is a namespace. So this commit makes `Sema::isStdInitializerList` account for that. I'm really new to clang so I'm not 100% sure that was the issue, it seems so and it fixes compilation. Also I probably need to add tests but I'd like someone to approve the idea first. Fixes #118218
1 parent f33e236 commit 9f1e9f6

File tree

3 files changed

+42
-1
lines changed

3 files changed

+42
-1
lines changed
 

‎clang/docs/ReleaseNotes.rst

+2
Original file line numberDiff line numberDiff line change
@@ -810,6 +810,8 @@ Bug Fixes to C++ Support
810810
- Fixed an incorrect lambda scope of generic lambdas that caused Clang to crash when computing potential lambda
811811
captures at the end of a full expression. (#GH115931)
812812
- Clang no longer rejects deleting a pointer of incomplete enumeration type. (#GH99278)
813+
- Fixed recognition of ``std::initializer_list`` when it's surrounded with ``extern "C++"`` and exported
814+
out of a module (which is the case e.g. in MSVC's implementation of ``std`` module). (#GH118218)
813815

814816
Bug Fixes to AST Handling
815817
^^^^^^^^^^^^^^^^^^^^^^^^^

‎clang/lib/Sema/SemaDeclCXX.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -11931,7 +11931,7 @@ bool Sema::isStdInitializerList(QualType Ty, QualType *Element) {
1193111931
if (TemplateClass->getIdentifier() !=
1193211932
&PP.getIdentifierTable().get("initializer_list") ||
1193311933
!getStdNamespace()->InEnclosingNamespaceSetOf(
11934-
TemplateClass->getDeclContext()))
11934+
TemplateClass->getNonTransparentDeclContext()))
1193511935
return false;
1193611936
// This is a template called std::initializer_list, but is it the right
1193711937
// template?
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// RUN: rm -rf %t
2+
// RUN: mkdir -p %t
3+
// RUN: split-file %s %t
4+
//
5+
// RUN: %clang_cc1 -std=c++20 %t/std.cppm -emit-module-interface -o %t/std.pcm
6+
// RUN: %clang_cc1 -std=c++20 %t/mod.cppm -fprebuilt-module-path=%t -emit-module-interface -o %t/mod.pcm
7+
// RUN: %clang_cc1 -std=c++20 -fprebuilt-module-path=%t -verify %t/main.cpp
8+
9+
//--- std.cppm
10+
export module std;
11+
12+
extern "C++" {
13+
namespace std {
14+
export template <class E>
15+
class initializer_list {
16+
const E* _1;
17+
const E* _2;
18+
};
19+
}
20+
}
21+
22+
//--- mod.cppm
23+
export module mod;
24+
25+
import std;
26+
27+
export struct A {
28+
void func(std::initializer_list<int>) {}
29+
};
30+
31+
//--- main.cpp
32+
// expected-no-diagnostics
33+
import std;
34+
import mod;
35+
36+
int main() {
37+
A{}.func({1,1});
38+
return 0;
39+
}

0 commit comments

Comments
 (0)
Please sign in to comment.