llvm / llvm/llvm-project

[libc++] std::map crashes when linking C++11 and C++14+ translation units

Open
#218,524 1 comment 0 reactions 1 assignee Claimed by @ldionne View on GitHub
libc++
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

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.