summaryrefslogtreecommitdiffstats
path: root/libcxx/test/utilities/tuple
diff options
context:
space:
mode:
authorEric Fiselier <eric@efcs.ca>2014-10-28 06:31:22 +0000
committerEric Fiselier <eric@efcs.ca>2014-10-28 06:31:22 +0000
commit295bce1130906e415534b8aa9104b75cb553d173 (patch)
tree328ed3604a820c63a1d0c47fa161f04aa5250826 /libcxx/test/utilities/tuple
parent44067eead197169274e235562a242f9747be5cc3 (diff)
downloadbcm5719-llvm-295bce1130906e415534b8aa9104b75cb553d173.tar.gz
bcm5719-llvm-295bce1130906e415534b8aa9104b75cb553d173.zip
[libcxx] Delay evaluation of __make_tuple_types to prevent blowing the max template instantiation depth. Fixes Bug #18345
Summary: http://llvm.org/bugs/show_bug.cgi?id=18345 Tuple's constructor and assignment operators for "tuple-like" types evaluates __make_tuple_types unnecessarily. In the case of a large array this can blow the template instantiation depth. Ex: ``` #include <array> #include <tuple> #include <memory> typedef std::array<int, 1256> array_t; typedef std::tuple<array_t> tuple_t; int main() { array_t a; tuple_t t(a); // broken t = a; // broken // make_shared uses tuple behind the scenes. This bug breaks this code. std::make_shared<array_t>(a); } ``` To prevent this from happening we delay the instantiation of `__make_tuple_types` until after we perform the length check. Currently `__make_tuple_types` is instantiated at the same time that the length check . Test Plan: Two tests have been added. One for the "tuple-like" constructors and another for the "tuple-like" assignment operator. Reviewers: mclow.lists, EricWF Reviewed By: EricWF Subscribers: K-ballo, cfe-commits Differential Revision: http://reviews.llvm.org/D4467 llvm-svn: 220769
Diffstat (limited to 'libcxx/test/utilities/tuple')
-rw-r--r--libcxx/test/utilities/tuple/tuple.tuple/tuple.assign/tuple_array_template_depth.pass.cpp32
-rw-r--r--libcxx/test/utilities/tuple/tuple.tuple/tuple.cnstr/tuple_array_template_depth.pass.cpp34
2 files changed, 66 insertions, 0 deletions
diff --git a/libcxx/test/utilities/tuple/tuple.tuple/tuple.assign/tuple_array_template_depth.pass.cpp b/libcxx/test/utilities/tuple/tuple.tuple/tuple.assign/tuple_array_template_depth.pass.cpp
new file mode 100644
index 00000000000..f62d2fed483
--- /dev/null
+++ b/libcxx/test/utilities/tuple/tuple.tuple/tuple.assign/tuple_array_template_depth.pass.cpp
@@ -0,0 +1,32 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <tuple>
+
+// template <class... Types> class tuple;
+
+// template <class Tuple, __tuple_assignable<Tuple, tuple> >
+// tuple & operator=(Tuple &&);
+
+// This test checks that we do not evaluate __make_tuple_types
+// on the array when it doesn't match the size of the tuple.
+
+#include <array>
+#include <tuple>
+
+// Use 1256 to try and blow the template instantiation depth for all compilers.
+typedef std::array<char, 1256> array_t;
+typedef std::tuple<array_t> tuple_t;
+
+int main()
+{
+ array_t arr;
+ tuple_t tup;
+ tup = arr;
+}
diff --git a/libcxx/test/utilities/tuple/tuple.tuple/tuple.cnstr/tuple_array_template_depth.pass.cpp b/libcxx/test/utilities/tuple/tuple.tuple/tuple.cnstr/tuple_array_template_depth.pass.cpp
new file mode 100644
index 00000000000..65a1c701c51
--- /dev/null
+++ b/libcxx/test/utilities/tuple/tuple.tuple/tuple.cnstr/tuple_array_template_depth.pass.cpp
@@ -0,0 +1,34 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <tuple>
+
+// template <class... Types> class tuple;
+
+// template <class Tuple, __tuple_convertible<Tuple, tuple> >
+// tuple(Tuple &&);
+//
+// template <class Tuple, __tuple_constructible<Tuple, tuple> >
+// tuple(Tuple &&);
+
+// This test checks that we do not evaluate __make_tuple_types
+// on the array.
+
+#include <array>
+#include <tuple>
+
+// Use 1256 to try and blow the template instantiation depth for all compilers.
+typedef std::array<char, 1256> array_t;
+typedef std::tuple<array_t> tuple_t;
+
+int main()
+{
+ array_t arr;
+ tuple_t tup(arr);
+}
OpenPOWER on IntegriCloud