Fix reference invalidation in SmallVector APIs that pass in a T, taking it by value when it's small enough and trivially copyable, and doing a pointer-to-index-to-pointer dance otherwise.
This doesn't fix all possible reference invalidation, but if it avoids the compile-time regressions from https://reviews.llvm.org/D87326 (which does fix them all) it seems like a good incremental step. The mental model also seems more clear than https://reviews.llvm.org/D91467 (which only fixed invalidation for small enough, trivially copyable T).
I'm currently building a few variants of clang (matching how the patches are sequenced in my local tree (probably they should be committed separately so they can be reverted individually if necessary, but I figured it made more sense to start with a single Phab review)) to test effects on compile-time:
- baseline
- fix only push_back and single-element insert (tied together since insert uses `push_back)
- fix also N-element versions of append and insert (tied together since insert uses append)
- fix also resize
I'll start with compiling a "big" file a few times (in the other review I used llvm/lib/Target/X86/X86ISelLowering.cpp), but I'm happy to do more work if it seems prudent.
Absurd C++ pedantry, but I believe op< on pointers to unrelated objects is unspecified in C++? ("If two pointers are not specified to compare greater or compare equal, the result of the comparison is unspecified. An unspecified result may be nondeterministic, and need not be consistent even for multiple evaluations of the same expression with the same operands in the same execution of the program" - https://en.cppreference.com/w/cpp/language/operator_comparison) but std::less is specified to handle this case: "A specialization of std::less for any pointer type yields a strict total order, even if the built-in operator< does not." - https://en.cppreference.com/w/cpp/utility/functional/less)
Because C++ is fun like that.