<html>
    <head>
      <base href="https://bugs.llvm.org/">
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW - [coroutines] Compiler incorrectly caches thread_local address across suspend-points"
   href="https://bugs.llvm.org/show_bug.cgi?id=47835">47835</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>[coroutines] Compiler incorrectly caches thread_local address across suspend-points
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>clang
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>trunk
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>PC
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>All
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>enhancement
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>P
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>C++2a
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>unassignedclangbugs@nondot.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>lewissbaker@gmail.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>blitzrakete@gmail.com, erik.pilkington@gmail.com, llvm-bugs@lists.llvm.org, richard-llvm@metafoo.co.uk
          </td>
        </tr></table>
      <p>
        <div>
        <pre>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: <a href="https://godbolt.org/z/o1djvq">https://godbolt.org/z/o1djvq</a>

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".</pre>
        </div>
      </p>


      <hr>
      <span>You are receiving this mail because:</span>

      <ul>
          <li>You are on the CC list for the bug.</li>
      </ul>
    </body>
</html>