Skip to content

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
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