[libc++] std::map crashes when linking C++11 and C++14+ translation units
- Dominant language
- LLVM
- Stars
- 40.5k
- Forks
- 18.7k
- PR merge metrics
- PR metrics pending
Description
This is being lifted from a bug report received downstream (rdar://185542382)
```cpp
// count.cpp — -std=c++23. Emits EAGER operator(); does NOT emit __find_equal.
#include
#include
unsigned long count_key(std::map& m, const std::string& k) { return m.count(k); }
```
```cpp
// put.cpp — -std=c++11. Emits LAZY __find_equal (expects sret operator()).
#include
#include
void put(std::map& m, const std::string& k) { m[k] = k; }
```
```cpp
// main.cpp — any std
#include
#include
#include
void put(std::map&, const std::string&);
int main() {
std::map m;
put(m, "a"); std::printf("first ok\n");
put(m, "b"); // SIGSEGV
std::printf("second ok\n");
}
```
```
clang++ -std=c++23 -O0 -c count.cpp; clang++ -std=c++11 -O0 -c put.cpp
clang++ -std=c++23 -O0 -c main.cpp
clang++ count.o put.o main.o -o crash && ./crash
```
This is caused by the fact that we guard the `__lazy_synth_three_way_comparator` specializations with C++14:
https://github.com/llvm/llvm-project/blob/eb5115595fee15ebd48f595f6da9bece3de13a9f/libcxx/include/map#L683-L725
As a result, in C++03 and C++11, `operator()` returns `__lazy_compare_result` (the base template) while in C++14 and above it returns `__eager_compare_result`.
Contributor guide
Assessment
This issue has not been assessed yet.