Skip to content

[libc++] Prohibits initializer_list specializations. #128042

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 1, 2025

Conversation

mordante
Copy link
Member

This relies on Clang's no_specializations attribute which is not supported by GCC.

Implements:

  • LWG2129: User specializations of std::initializer_list

Fixes: #126270

@mordante mordante requested a review from a team as a code owner February 20, 2025 18:18
@llvmbot llvmbot added the libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi. label Feb 20, 2025
@llvmbot
Copy link
Member

llvmbot commented Feb 20, 2025

@llvm/pr-subscribers-libcxx

Author: Mark de Wever (mordante)

Changes

This relies on Clang's no_specializations attribute which is not supported by GCC.

Implements:

  • LWG2129: User specializations of std::initializer_list

Fixes: #126270


Full diff: https://github.com/llvm/llvm-project/pull/128042.diff

3 Files Affected:

  • (modified) libcxx/docs/Status/Cxx17Issues.csv (+1-1)
  • (modified) libcxx/include/initializer_list (+1-1)
  • (added) libcxx/test/std/language.support/support.initlist/support.initlist.syn/specialization.verify.cpp (+24)
diff --git a/libcxx/docs/Status/Cxx17Issues.csv b/libcxx/docs/Status/Cxx17Issues.csv
index 477f3d363a4e2..d09b37f1d3900 100644
--- a/libcxx/docs/Status/Cxx17Issues.csv
+++ b/libcxx/docs/Status/Cxx17Issues.csv
@@ -12,7 +12,7 @@
 "`LWG2404 <https://wg21.link/LWG2404>`__","``mismatch()``\ 's complexity needs to be updated","2014-11 (Urbana)","|Complete|","",""
 "`LWG2408 <https://wg21.link/LWG2408>`__","SFINAE-friendly ``common_type``\  / ``iterator_traits``\  is missing in C++14","2014-11 (Urbana)","|Complete|","",""
 "`LWG2106 <https://wg21.link/LWG2106>`__","``move_iterator``\  wrapping iterators returning prvalues","2014-11 (Urbana)","|Complete|","",""
-"`LWG2129 <https://wg21.link/LWG2129>`__","User specializations of ``std::initializer_list``\ ","2014-11 (Urbana)","|Complete|","",""
+"`LWG2129 <https://wg21.link/LWG2129>`__","User specializations of ``std::initializer_list``\ ","2014-11 (Urbana)","|Complete|","21",""
 "`LWG2212 <https://wg21.link/LWG2212>`__","``tuple_size``\  for ``const pair``\  request <tuple> header","2014-11 (Urbana)","|Complete|","",""
 "`LWG2217 <https://wg21.link/LWG2217>`__","``operator==(sub_match, string)``\  slices on embedded '\0's","2014-11 (Urbana)","|Complete|","",""
 "`LWG2230 <https://wg21.link/LWG2230>`__","""see below"" for ``initializer_list``\  constructors of unordered containers","2014-11 (Urbana)","|Complete|","",""
diff --git a/libcxx/include/initializer_list b/libcxx/include/initializer_list
index 07c51f32fee7d..3967ad8aaef7c 100644
--- a/libcxx/include/initializer_list
+++ b/libcxx/include/initializer_list
@@ -59,7 +59,7 @@ namespace std // purposefully not versioned
 #  ifndef _LIBCPP_CXX03_LANG
 
 template <class _Ep>
-class _LIBCPP_TEMPLATE_VIS initializer_list {
+class _LIBCPP_TEMPLATE_VIS _LIBCPP_NO_SPECIALIZATIONS initializer_list {
   const _Ep* __begin_;
   size_t __size_;
 
diff --git a/libcxx/test/std/language.support/support.initlist/support.initlist.syn/specialization.verify.cpp b/libcxx/test/std/language.support/support.initlist/support.initlist.syn/specialization.verify.cpp
new file mode 100644
index 0000000000000..5ea36a47cee1a
--- /dev/null
+++ b/libcxx/test/std/language.support/support.initlist/support.initlist.syn/specialization.verify.cpp
@@ -0,0 +1,24 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03
+
+// template<class E> class initializer_list;
+//
+// If an explicit specialization or partial specialization of initializer_list
+// is declared, the program is ill-formed.
+
+#include <initializer_list>
+
+// expected-error@+2 {{'initializer_list' cannot be specialized: Users are not allowed to specialize this standard library entity}}
+template <>
+class std::initializer_list<int> {};
+
+// expected-error@+2 {{'initializer_list' cannot be specialized: Users are not allowed to specialize this standard library entity}}
+template <typename T>
+class std::initializer_list<T*> {};

@ldionne
Copy link
Member

ldionne commented Feb 20, 2025

I don't know why we claimed to implement LWG2129 (#103237), but this patch does the correct thing. Thanks!

@frederick-vs-ja
Copy link
Contributor

I don't know why we claimed to implement LWG2129 (#103237), but this patch does the correct thing. Thanks!

Per 3687d3c, it seems expected that compilers would handle LWG2129 by detecting initializer_list specializations directly.
But currently only MSVC and EDG perform such check, and neither GCC nor Clang diagnose the following:

#include <initializer_list>

template<class T>
class std::initializer_list<T**> {
private:
  T***                m_array_;
  decltype(sizeof(0)) m_len_;
};

(Godbolt link, EDG demo)

This relies on Clang's no_specializations attribute which is not
supported by GCC.

Implements:
- LWG2129: User specializations of std::initializer_list

Fixes: llvm#126270
@mordante
Copy link
Member Author

mordante commented Mar 1, 2025

I don't know why we claimed to implement LWG2129 (#103237), but this patch does the correct thing. Thanks!

Per 3687d3c, it seems expected that compilers would handle LWG2129 by detecting initializer_list specializations directly. But currently only MSVC and EDG perform such check, and neither GCC nor Clang diagnose the following:

GCC indeed only seems not to diagnose partial specialization. Clang indeed does neither, which was the reason for this patch.

@mordante mordante merged commit d2b09e2 into llvm:main Mar 1, 2025
85 checks passed
@mordante mordante deleted the review/LWG2129 branch March 1, 2025 11:34
jph-13 pushed a commit to jph-13/llvm-project that referenced this pull request Mar 21, 2025
This relies on Clang's no_specializations attribute which is not
supported by GCC.

Implements:
- LWG2129: User specializations of std::initializer_list

Fixes: llvm#126270
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Clang does not diagnose an explicit specialization or partial specialization of initializer_list
4 participants