diff options
| author | Eric Fiselier <eric@efcs.ca> | 2014-10-28 06:31:22 +0000 |
|---|---|---|
| committer | Eric Fiselier <eric@efcs.ca> | 2014-10-28 06:31:22 +0000 |
| commit | 295bce1130906e415534b8aa9104b75cb553d173 (patch) | |
| tree | 328ed3604a820c63a1d0c47fa161f04aa5250826 /libcxx/test/utilities/tuple | |
| parent | 44067eead197169274e235562a242f9747be5cc3 (diff) | |
| download | bcm5719-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')
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); +} |

