summaryrefslogtreecommitdiffstats
path: root/clang/test
diff options
context:
space:
mode:
authorReid Kleckner <rnk@google.com>2019-08-15 19:45:28 +0000
committerReid Kleckner <rnk@google.com>2019-08-15 19:45:28 +0000
commited399a69e2a0fc40418c3bc955e5cb2787aa93fa (patch)
treecb0c9361ca9297c5261dd9c0fcabd66ebc4f17a3 /clang/test
parent82bfd1d25712f8c1b714614f3df559c773f08988 (diff)
downloadbcm5719-llvm-ed399a69e2a0fc40418c3bc955e5cb2787aa93fa.tar.gz
bcm5719-llvm-ed399a69e2a0fc40418c3bc955e5cb2787aa93fa.zip
[Sema] Implement DR2386 for C++17 structured binding
Allow implementations to provide complete definitions of std::tuple_size<T>, but to omit the 'value' member to signal that T is not tuple-like. The Microsoft standard library implements std::tuple_size<const T> this way. If the value member exists, clang still validates that it is an ICE, but if it does not, then the type is considered to not be tuple-like. Fixes PR33236 Reviewers: rsmith Differential Revision: https://reviews.llvm.org/D66040 llvm-svn: 369043
Diffstat (limited to 'clang/test')
-rw-r--r--clang/test/CXX/dcl.decl/dcl.decomp/p3.cpp2
-rw-r--r--clang/test/CXX/drs/dr23xx.cpp21
2 files changed, 22 insertions, 1 deletions
diff --git a/clang/test/CXX/dcl.decl/dcl.decomp/p3.cpp b/clang/test/CXX/dcl.decl/dcl.decomp/p3.cpp
index b3f0cf18744..9b030c1a2e1 100644
--- a/clang/test/CXX/dcl.decl/dcl.decomp/p3.cpp
+++ b/clang/test/CXX/dcl.decl/dcl.decomp/p3.cpp
@@ -12,7 +12,7 @@ void no_tuple_size_2() { auto [x, y] = A(); } // ok, decompose elementwise
struct Bad1 { int a, b; };
template<> struct std::tuple_size<Bad1> {};
-void no_tuple_size_3() { auto [x, y] = Bad1(); } // expected-error {{cannot decompose this type; 'std::tuple_size<Bad1>::value' is not a valid integral constant expression}}
+void no_tuple_size_3() { auto [x, y] = Bad1(); } // ok, omitting value is valid after DR2386
struct Bad2 {};
template<> struct std::tuple_size<Bad2> { const int value = 5; };
diff --git a/clang/test/CXX/drs/dr23xx.cpp b/clang/test/CXX/drs/dr23xx.cpp
index 8e7a9a880bf..763abd5368e 100644
--- a/clang/test/CXX/drs/dr23xx.cpp
+++ b/clang/test/CXX/drs/dr23xx.cpp
@@ -40,6 +40,27 @@ namespace dr2353 { // dr2353: 9
#pragma clang __debug dump not_use_2
}
+#if __cplusplus >= 201707L
+// Otherwise, if the qualified-id std::tuple_size<E> names a complete class
+// type **with a member value**, the expression std::tuple_size<E>::value shall
+// be a well-formed integral constant expression
+namespace dr2386 { // dr2386: 9
+struct Bad1 { int a, b; };
+struct Bad2 { int a, b; };
+} // namespace dr2386
+namespace std {
+template <typename T> struct tuple_size;
+template <> struct std::tuple_size<dr2386::Bad1> {};
+template <> struct std::tuple_size<dr2386::Bad2> {
+ static const int value = 42;
+};
+} // namespace std
+namespace dr2386 {
+void no_value() { auto [x, y] = Bad1(); }
+void wrong_value() { auto [x, y] = Bad2(); } // expected-error {{decomposes into 42 elements}}
+} // namespace dr2386
+#endif
+
namespace dr2387 { // dr2387: 9
#if __cplusplus >= 201402L
template<int> int a = 0;
OpenPOWER on IntegriCloud