This is an archive of the discontinued LLVM Phabricator instance.

[libcxx] Delay evaluation of __make_tuple_types to prevent blowing the max template instantiation depth. Fixes Bug #18345
ClosedPublic

Authored by EricWF on Jul 10 2014, 4:51 PM.

Details

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 .

Diff Detail

Event Timeline

EricWF updated this revision to Diff 11300.Jul 10 2014, 4:51 PM
EricWF retitled this revision from to [libcxx] Delay evaluation of __make_tuple_types to prevent blowing the max template instantiation depth. Fixes Bug #18345.
EricWF updated this object.
EricWF edited the test plan for this revision. (Show Details)
EricWF added a reviewer: mclow.lists.
EricWF set the repository for this revision to rL LLVM.
EricWF added a subscriber: Unknown Object (MLST).

Have you considered a non-recursive implementation of __tuple_constructible_imp? For instance, checking whether foo(declval<Up>()...) is well-formed given void foo(Tp...).

I haven't actually considered that. I'm actually leaning towards making __tuple_constructible_imp (and similar) lazy to prevent compile errors where possible. Either way I think I'll prototype something similar to your suggestion to see if it helps compile times.

However I'm more interested in improving __make_tuple_types since it is evaluated multiple times before __tuple_constructible_imp.

Ping. This is the most important fix I have waiting for review. This already breaks make_shared for arrays. Without this fix both experimental/any + experimental/memory_resource will also have bugs in them.

Ping. This bug has the potential to break a lot of code.

Looks good to me. Some notes attached.

include/__tuple
222

No need to name these parameters

235

..or these

249

..or these

273

..or these

286

..or these

310

..or these

test/utilities/tuple/tuple.tuple/tuple.assign/tuple_array_template_depth.pass.cpp
19

This comment is true only for mismatched tuple-sizes

EricWF updated this revision to Diff 15281.Oct 22 2014, 3:30 PM

Address K-ballo's comments.

EricWF accepted this revision.Oct 27 2014, 11:40 PM
EricWF added a reviewer: EricWF.

Accepting after @K-ballo did an informal review and after offline discussions with @mclow.lists.

This revision is now accepted and ready to land.Oct 27 2014, 11:40 PM
EricWF closed this revision.Oct 27 2014, 11:41 PM