https://github.com/jijjijj updated https://github.com/llvm/llvm-project/pull/118537
>From d0a3059a10b7ceeb7e9c27068266f8c41e794203 Mon Sep 17 00:00:00 2001 From: jijjijj <realjijj...@gmail.com> Date: Tue, 3 Dec 2024 22:57:34 +0300 Subject: [PATCH 1/2] Fix std::initializer_list recognition if it's exported out of a module 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. --- clang/lib/Sema/SemaDeclCXX.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 7e8e321c4b90e6..4572229562ed3b 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -11919,8 +11919,12 @@ bool Sema::isStdInitializerList(QualType Ty, QualType *Element) { CXXRecordDecl *TemplateClass = Template->getTemplatedDecl(); if (TemplateClass->getIdentifier() != &PP.getIdentifierTable().get("initializer_list") || - !getStdNamespace()->InEnclosingNamespaceSetOf( - TemplateClass->getDeclContext())) + !(getStdNamespace()->InEnclosingNamespaceSetOf( + TemplateClass->getDeclContext()) || + // if decl context is an export from module we need to check the parent + (TemplateClass->getDeclContext()->getDeclKind() == Decl::Kind::Export && + getStdNamespace()->InEnclosingNamespaceSetOf( + TemplateClass->getDeclContext()->getParent())))) return false; // This is a template called std::initializer_list, but is it the right // template? >From 932764c8eb1b87364ffbcf8311a38cd0b8ff0b9d Mon Sep 17 00:00:00 2001 From: jijjijj <realjijj...@gmail.com> Date: Sat, 7 Dec 2024 19:24:29 +0300 Subject: [PATCH 2/2] Fix std::initializer_list recognition if it's exported out of a module - Improve implementation - Add a regression test - Add release notes --- clang/docs/ReleaseNotes.rst | 2 + clang/lib/Sema/SemaDeclCXX.cpp | 8 +--- ...hrough-export-and-linkage-issue-118218.cpp | 39 +++++++++++++++++++ 3 files changed, 43 insertions(+), 6 deletions(-) create mode 100644 clang/test/Modules/initializer-list-recognition-through-export-and-linkage-issue-118218.cpp diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 59e3a6609123d2..2e25f487bfb528 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -796,6 +796,8 @@ Bug Fixes to C++ Support - Fixed an assertion failure caused by mangled names with invalid identifiers. (#GH112205) - Fixed an incorrect lambda scope of generic lambdas that caused Clang to crash when computing potential lambda captures at the end of a full expression. (#GH115931) +- Fixed recognition of ``std::initializer_list`` when it's surrounded with ``extern "C++"`` and exported + out of a module. (#GH118218) Bug Fixes to AST Handling ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 4436b521d21928..d5229143709c03 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -11926,12 +11926,8 @@ bool Sema::isStdInitializerList(QualType Ty, QualType *Element) { CXXRecordDecl *TemplateClass = Template->getTemplatedDecl(); if (TemplateClass->getIdentifier() != &PP.getIdentifierTable().get("initializer_list") || - !(getStdNamespace()->InEnclosingNamespaceSetOf( - TemplateClass->getDeclContext()) || - // if decl context is an export from module we need to check the parent - (TemplateClass->getDeclContext()->getDeclKind() == Decl::Kind::Export && - getStdNamespace()->InEnclosingNamespaceSetOf( - TemplateClass->getDeclContext()->getParent())))) + !getStdNamespace()->InEnclosingNamespaceSetOf( + TemplateClass->getNonTransparentDeclContext())) return false; // This is a template called std::initializer_list, but is it the right // template? diff --git a/clang/test/Modules/initializer-list-recognition-through-export-and-linkage-issue-118218.cpp b/clang/test/Modules/initializer-list-recognition-through-export-and-linkage-issue-118218.cpp new file mode 100644 index 00000000000000..70ad8951e63356 --- /dev/null +++ b/clang/test/Modules/initializer-list-recognition-through-export-and-linkage-issue-118218.cpp @@ -0,0 +1,39 @@ +// RUN: rm -rf %t +// RUN: mkdir -p %t +// RUN: split-file %s %t +// +// RUN: %clang_cc1 -std=c++20 %t/std.cppm -emit-module-interface -o %t/std.pcm +// RUN: %clang_cc1 -std=c++20 %t/mod.cppm -fprebuilt-module-path=%t -emit-module-interface -o %t/mod.pcm +// RUN: %clang_cc1 -std=c++20 -fprebuilt-module-path=%t -verify %t/main.cpp + +//--- std.cppm +export module std; + +extern "C++" { + namespace std { + export template <class E> + class initializer_list { + const E* _1; + const E* _2; + }; + } +} + +//--- mod.cppm +export module mod; + +import std; + +export struct A { + void func(std::initializer_list<int>) {} +}; + +//--- main.cpp +// expected-no-diagnostics +import std; +import mod; + +int main() { + A{}.func({1,1}); + return 0; +} \ No newline at end of file _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits