<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/55406>55406</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            -Wthread-safety coroutine ICE
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            new issue
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          urnathan
      </td>
    </tr>
</table>

<pre>
    this use of a stmt-expression inside a co_return causes an ICE

```
Task Foo() {
  co_return ({ static int frame = 0; 0; });
}
```
On today's trunk:
```
zathras:18>build/bin/clang++ -c -std=c++17 -fcoroutines-ts -Wthread-safety coro-thread-ice.cc
clang++: /home/nathan/llvm/trunk/clang/lib/Analysis/ThreadSafety.cpp:530: (anonymous namespace)::LocalVariableMap::Context (anonymous namespace)::LocalVariableMap::addDefinition(const clang::NamedDecl *, const clang::Expr *, (anonymous namespace)::LocalVariableMap::Context): Assertion `!Ctx.contains(D)' failed.
...
#11 0x000000000bef2835 (anonymous namespace)::LocalVariableMap::addDefinition(clang::NamedDecl const*, clang::Expr const*, llvm::ImmutableMap<clang::NamedDecl const*, unsigned int, llvm::ImutKeyValueInfo<clang::NamedDecl const*, unsigned int>>) /data/users/nathans/llvm/trunk/clang/lib/Analysis/ThreadSafety.cpp:0:5
#12 0x000000000beefd18 (anonymous namespace)::VarMapBuilder::VisitDeclStmt(clang::DeclStmt const*) /data/users/nathans/llvm/trunk/clang/lib/Analysis/ThreadSafety.cpp:618:21
#13 0x000000000beeddb9 clang::StmtVisitorBase<llvm::make_const_ptr, (anonymous namespace)::VarMapBuilder, void>::Visit(clang::Stmt const*) /data/users/nathans/llvm/trunk/build/tools/clang/include/clang/AST/StmtNodes.inc:97:1
#14 0x000000000bee7549 (anonymous namespace)::LocalVariableMap::traverseCFG(clang::CFG*, clang::PostOrderCFGView const*, std::vector<(anonymous namespace)::CFGBlockInfo, std::allocator<(anonymous namespace)::CFGBlockInfo>>&) /data/users/nathans/llvm/trunk/clang/lib/Analysis/ThreadSafety.cpp:780:11
#15 0x000000000bee4fb2 (anonymous namespace)::ThreadSafetyAnalyzer::runAnalysis(clang::AnalysisDeclContext&) /data/users/nathans/llvm/trunk/clang/lib/Analysis/ThreadSafety.cpp:2252:15
#16 0x000000000bee4d23 clang::threadSafety::runThreadSafetyAnalysis(clang::AnalysisDeclContext&, clang::threadSafety::ThreadSafetyHandler&, clang::threadSafety::BeforeSet**) /data/users/nathans/llvm/trunk/clang/lib/Analysis/ThreadSafety.cpp:2466:1
#17 0x000000000aba3948 clang::sema::AnalysisBasedWarnings::IssueWarnings(clang::sema::AnalysisBasedWarnings::Policy, clang::sema::FunctionScopeInfo*, clang::Decl const*, clang::QualType) /data/users/nathans/llvm/trunk/clang/lib/Sema/AnalysisBasedWarnings.cpp:2360:14
```

Here's the full reproducer:
```
// -cc1 -triple x86_64 -Wthread-safety -std=c++17 -fcoroutines-ts

// ICE: clang/lib/Analysis/ThreadSafety.cpp:530: (anonymous namespace)::LocalVariableMap::Context (anonymous namespace)::LocalVariableMap::addDefinition(const clang::NamedDecl *, const clang::Expr *, (anonymous namespace)::LocalVariableMap::Context): Assertion `!Ctx.contains(D)' failed.

#if USE_HEADER
#include <coroutine>
#else
namespace std
{
typedef long unsigned int size_t;
typedef decltype(nullptr) nullptr_t;
template<typename...> using __void_t = void;

inline namespace __n4861 {
template <typename _Result, typename = void>
struct __coroutine_traits_impl {};
template <typename _Result>
struct __coroutine_traits_impl<_Result,
                               __void_t<typename _Result::promise_type>>
{
  using promise_type = typename _Result::promise_type;
};
template <typename _Result, typename...>
struct coroutine_traits : __coroutine_traits_impl<_Result> {};
template <typename _Promise = void>
struct coroutine_handle;
template <> struct
coroutine_handle<void>
{
public:
  constexpr coroutine_handle() noexcept : _M_fr_ptr(0) {}
  constexpr coroutine_handle(std::nullptr_t __h) noexcept
      : _M_fr_ptr(__h)
  {}
  coroutine_handle& operator=(std::nullptr_t) noexcept
  {
    _M_fr_ptr = nullptr;
    return *this;
  }
public:
  constexpr void* address() const noexcept { return _M_fr_ptr; }
  constexpr static coroutine_handle from_address(void* __a) noexcept
  {
    coroutine_handle __self;
    __self._M_fr_ptr = __a;
    return __self;
  }
public:
  constexpr explicit operator bool() const noexcept
  {
    return bool(_M_fr_ptr);
  }
  bool done() const noexcept { return __builtin_coro_done(_M_fr_ptr); }
  void operator()() const { resume(); }
  void resume() const { __builtin_coro_resume(_M_fr_ptr); }
  void destroy() const { __builtin_coro_destroy(_M_fr_ptr); }
protected:
  void* _M_fr_ptr;
};
template <typename _Promise>
struct coroutine_handle : coroutine_handle<>
{
  using coroutine_handle<>::coroutine_handle;
  static coroutine_handle from_promise(_Promise& p)
  {
    coroutine_handle __self;
    __self._M_fr_ptr
        = __builtin_coro_promise((char*) &p, __alignof(_Promise), true);
    return __self;
  }
  coroutine_handle& operator=(std::nullptr_t) noexcept
  {
    coroutine_handle<>::operator=(nullptr);
    return *this;
  }
  constexpr static coroutine_handle from_address(void* __a) noexcept
  {
    coroutine_handle __self;
    __self._M_fr_ptr = __a;
    return __self;
  }
  _Promise& promise() const
  {
    void* __t
        = __builtin_coro_promise (this->_M_fr_ptr, __alignof(_Promise), false);
    return *static_cast<_Promise*>(__t);
  }
};
struct noop_coroutine_promise
{
};
void __dummy_resume_destroy() __attribute__((__weak__));
void __dummy_resume_destroy() {}
struct __noop_coro_frame
{
  void (*__r)() = __dummy_resume_destroy;
  void (*__d)() = __dummy_resume_destroy;
  struct noop_coroutine_promise __p;
} __noop_coro_fr __attribute__((__weak__));
template <>
struct coroutine_handle<noop_coroutine_promise> : public coroutine_handle<>
{
  using _Promise = noop_coroutine_promise;
public:
  constexpr explicit operator bool() const noexcept { return true; }
  constexpr bool done() const noexcept { return false; }
  void operator()() const noexcept {}
  void resume() const noexcept {}
  void destroy() const noexcept {}
  _Promise& promise() const
  {
    return *static_cast<_Promise*>(
        __builtin_coro_promise(this->_M_fr_ptr, __alignof(_Promise), false));
  }
private:
  friend coroutine_handle<noop_coroutine_promise> noop_coroutine() noexcept;
  coroutine_handle() noexcept { this->_M_fr_ptr = (void*) &__noop_coro_fr; }
};
using noop_coroutine_handle = coroutine_handle<noop_coroutine_promise>;
inline noop_coroutine_handle noop_coroutine() noexcept
{
  return noop_coroutine_handle();
}
struct suspend_always
{
  constexpr bool await_ready() const noexcept { return false; }
  constexpr void await_suspend(coroutine_handle<>) const noexcept {}
  constexpr void await_resume() const noexcept {}
};
struct suspend_never
{
  constexpr bool await_ready() const noexcept { return true; }
  constexpr void await_suspend(coroutine_handle<>) const noexcept {}
  constexpr void await_resume() const noexcept {}
};
}
}
#endif

class Task;

class Promise {
public:
  std::suspend_always initial_suspend() noexcept { return {}; }
  std::suspend_always final_suspend() noexcept { return {}; }

  Promise() noexcept = default;
  Task get_return_object() noexcept;
  void unhandled_exception() noexcept ;
  
  void return_value(int&& value) ;
};

class Task {
public:
  using promise_type = Promise;
  using handle_t = std::coroutine_handle<promise_type>;
  Task(const Task& t) = delete;
  Task(Task&& t) noexcept ;
  ~Task() ;
  Task& operator=(Task t) noexcept ;
};

Task Foo() {
  co_return ({ static int frame = 0; 0; });
}
```
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJztWllz47gR_jX0C0oqidT5oAfJR2Yq2d3JejL7yAJJ0EIMESwCtK359WkAPACKuuz1ViqVGZUs4fi68fWBBqiIJ_uV3FKBSkEQTxFGQu7kgLzlBRGC8gzRTNCEQEfMw4LIsshQjGG0QDhDX2_vvdGdN1pX77NR9dJfv2PxjB449_yF5y-RN9-YdmRhqb75BqRiSWMQJlFa4B1BXnCHRl6wMW_e_A4Q4FMlB772CfwtQ5IneO_5c4FkUWbPXtCv2k8stwUW0D1eeMF9VFKWeP5DRDN4jxnOnjx_Ay80iNFAyATUiU3LeI4GacwLXkqaETGQAg3-ADCCk4HAKZF7pHoHVRONyTCOjVALFwTD0h-2fEfgTwbaYCWZsZcd_DGqN4o8MBrB-zrDbC-ogI_fNfijFjeM8xzgpsHIgC5wxrP9jpcCZcCkyHFMNHlreP2Dx5j9wAXFESO_4Ny03vJMkjf5vsk4Se5ISjMqwV0AIeaZkMiorgf8CkAwJGaAv_b8W3Qw4h7cre78yALMKLQWghRKG6Ts7Y9v5dsQZEoMvgzw2pX8OUoxZSQZGtsMh9UHzw_GYzR6G9X_IpL6i2D6J5HTR4vmo-amw4rdp71Dd33d7UrZCLo9i1pCED9lJFEB1kUq5d_J_gdmJfmapfxqtOBevVR4-w8Jlhj-QHYoROPW4mN-rbx62prGd01D0mS8OGcasArwtFExToqqiQoq1cIeId25dqlbrSV_2uJmKvus_XG7vqCzviSJlrZTKM208rzYYEHAXK0td_iZhFrrMJfFBcHkEgPjXzhNtEUbjlxuPsJLnWMl50xYPNEsZmVCrJb143d4V7J-5QkRQxgBspdzla1bpiYdpubTyfJ9QSoL_ALKk9uHv7nL1Q3dsPzGhfytAMKg9wclr05o6K1CjXohMZgIzHNGIwDZMB4_69izATCDZnw9RhWPs0_02vlCBeXYssW0Y4tJGvnnbGEDa3k_6-AElVoFbHvUrSpEm5T_mSv1_amvlmoloFl3qYkf2O4hLZRmOQdrvXhpt6exbeAvOEuYiuPz0zYk5QV5JMZtPzPD-ZPZzI3buU0gjnCwnCxsbQXZYZcTleiSP3CR0exJVNuWECVpmhwmL5r_jTMa7zs8tTMfyixWO_ZjzHOzLR6kgVM79z9LzL7vc_IhXh-VNi29ziJqcoOZjsRJb41r3r-Qgph6eEtQWjKGCpIXPCljE269M_0HeEHtG4_RQBY0ZwS9LWbhbHJQ654rjp3jgYFVhwao0v5f3P5lxW0TfDRF_3q8D7_cr-_uf29bzQ6MVO1X205tInU_YVBo6C-Nynqfqs5i1aFMgsMnJEWMZ09OiYgE_UlC2Zze6oEJsCZ1lCwy8EtdsixR9dEeT3Y5w1LVOmq40kFV68E9HFohGFAYqrIllPrMaCqYjb1umjFYUEs3TMgmi9m4PZDWEpAlAoW_E1EyXS43ba2Eih0BsRtLQGyIC6GaoFKEFCC1BDirdlfSK-cySJjZKlYfp0_-q-nplan8C7LBjgqQomxhygfXsqgi2h6oqbgEzzqyX0SDRbexssNKlxOkQuI8VeArF5nim1H9qJ1bOVu92fbCKWlmfHXsP5h062A3POdlBLtSk5SRySXEHAM7GOZKJePkLSa5NDT8EqaFqfyhQKsuXOqbkjNgTdnZhB-wurVF2L7WlWaG1iO6YrvCZgg21cKUtne9svvkWt6IWuHaUnX2CKwRzfXSWl1vWV2NaifY1ubx1wiyv7oGq8g2mb2lfL6ppbRcVHdVB4jV_VaXDJSCw4WtmFpwGOKzHBxghaEgLHVYME1Dly4F3kPVwfRLmII36KKyMSmK4HjXS1jvIirZ1STLp5Z9iiA9ECU8I-dtEqoDJ_Cjk0NYzelIsKEV961nanhHiMEW5a6S3Tfd7remdXRpRp3TBg6_suD7c3jtsKOAkJMlnEhJYlmxcTbLey9N1lWiPJcfdaboyX_H95gjg3V-OJp90en4qjYkxU-tNyShvJOyPhRY7k5sosyxUauDqiK3uGiOXbNc7XkQlAwqJp46Wi71dliUxA2IC2L2kxLvKfO44G1Jd2Ve_p9Jmwg57mY5QBXLvfq1a5GXOpU6Vig2B2AKKwOcdKoUM3HMq0C8IT6MsVB1Yzt3rS-XFmEoj6RoO3VUSSHjPLcqtJoIN_7teTr3hWFS7nb7KlmGbiqEhUk4l0alJGFoYioMXwl-Vt-Wtmrnsexypam9G51D_TjqIFlpWA2wDsOi3SqMkXqlBf2TkysnnyQVpud2Fu-s5AreOgXtmSr49oiNVd0NO4ApIK7bCJxa_Bj8-cL5igLFrh50zj1WzF1ehJgou67OsHEuqC9ODe-rH46Mf0-qujhduIns6M747hzWn4rygr7oa4PGLdKCkiy5zn_dns65yxJ79oQGXnGwQO3c7QZWFQRu0DruY6dJEycdzZu66-6qZTag9WVJL-ppLrpxXLlHL1RTQrfLsjOMKAVUmgmY_hXvxQFyJxTxK5z5Q3VpeNzVT0Wke_Cr4CoV9J1fb9o6F1G9qJcGcM82WnOSkRdS_JmUnMx1_5WMOI3mgx-AajS17_1ihoVA6kconQtB09HsL0evX5r62HVHpK-DMbMIOYj0OjXWl042ucdgU5q9F7SG_uZkbut26A72ghTrq7DGZfTPc56IrH6KE_Lo33BEPJ7htNHKzJg8CU2_uRbvSGtzsbt5aTEv6qcGMEf_FGGm9puqZYm8vgNo15gnDHbkmvJbp1yoB5qVVBfHjVV6nPvghtThsHksYL7MkKyLuYQwIsnh8GpgM7aXuvl9NdphBjVS3OOWZuYI2CGbf-Evs26SVZAsgyW-kVQysur7sZSmWz0XuikLttpKmevHdPpx0ROV2zIaxnzXPjBTfwZgFOOvD1Q9DFRPjqbTyWh2s11N0mUySqLxZLqIfX80X6RRPI3mo2gZLaZxML5hOCJMrLzpxvP9jLwiDQGfvendDV35I5g1HftjP5gH_jCdxguy9OH_GE_TJPImI7LDlA2VHkNePN0UK61SVD4J6GRUSNF2guOqZyFEiwN8XMotL1bAsX4QeKNlr7Tu_wGvsFNY">