Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[libcxx] Delay evaluation of __make_tuple_types to prevent blowing th…
…e 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
- Loading branch information
Showing
3 changed files
with
117 additions
and
21 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
32 changes: 32 additions & 0 deletions
32
libcxx/test/utilities/tuple/tuple.tuple/tuple.assign/tuple_array_template_depth.pass.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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; | ||
} |
34 changes: 34 additions & 0 deletions
34
libcxx/test/utilities/tuple/tuple.tuple/tuple.cnstr/tuple_array_template_depth.pass.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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); | ||
} |