cxx/test/utilities/tuple/tuple.tuple/tuple.assign/tuple_array_template_depth.pass.cpp
Eric Fiselier 522aaf67ea [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

git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@220769 91177308-0d34-0410-b5e6-96231b3b80d8
2014-10-28 06:31:22 +00:00

33 lines
890 B
C++

//===----------------------------------------------------------------------===//
//
// 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;
}