[llvm-bugs] [Bug 47835] New: [coroutines] Compiler incorrectly caches thread_local address across suspend-points
via llvm-bugs
llvm-bugs at lists.llvm.org
Tue Oct 13 13:45:02 PDT 2020
https://bugs.llvm.org/show_bug.cgi?id=47835
Bug ID: 47835
Summary: [coroutines] Compiler incorrectly caches thread_local
address across suspend-points
Product: clang
Version: trunk
Hardware: PC
OS: All
Status: NEW
Severity: enhancement
Priority: P
Component: C++2a
Assignee: unassignedclangbugs at nondot.org
Reporter: lewissbaker at gmail.com
CC: blitzrakete at gmail.com, erik.pilkington at gmail.com,
llvm-bugs at lists.llvm.org, richard-llvm at metafoo.co.uk
The clang compiler is incorrectly caching the address of thread_local variables
across a suspend-point. It's possible that a coroutine could suspend and later
resume on a different thread, however, which could mean that the thread_local
instance from another thread might be accessed.
Godbolt: https://godbolt.org/z/o1djvq
For example compile the following program with: -std=c++20 -stdlib=libc++ -O2
-pthread
---
#include <experimental/coroutine>
#include <thread>
#include <unistd.h>
#include <pthread.h>
auto switch_to_new_thread(std::thread& out) {
struct awaitable {
std::thread* p_out;
bool await_ready() { return false; }
void await_suspend(std::experimental::coroutine_handle<> h) {
std::thread& out = *p_out;
out = std::thread([h]() mutable {
h.resume();
});
}
void await_resume() {}
};
return awaitable{&out};
}
struct task{
struct promise_type {
task get_return_object() { return {}; }
std::experimental::suspend_never initial_suspend() { return {}; }
std::experimental::suspend_never final_suspend() noexcept { return {}; }
void return_void() {}
void unhandled_exception() {}
};
};
thread_local int tls_variable = 0;
static task resuming_on_new_thread(std::thread& out) {
int* i = &tls_variable;
co_await switch_to_new_thread(out);
int* j = &tls_variable;
std::puts((i == j) ? "tls_variable address was same" : "tls_variable address
was different");
}
int main() {
std::thread out;
resuming_on_new_thread(out);
out.join();
}
------
Expected output: "tls_variable address was different"
Actual output: "tls_variable address was same"
If you compile with -O0 then it correctly outputs "tls_variable address was
different".
--
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20201013/3af6ef90/attachment-0001.html>
More information about the llvm-bugs
mailing list