Is the following code undefined behaviour or legal?
#include <thread>
#include <functional>
#include <atomic>
std::atomic<bool> b{false};
// these are defined in some other file. 
// actual implementation is not important for this question here
Handle insideFoo, continueFoo; // some type defined somewhere
void Wait(Handle h); // blocks current thread until someone calls Continue(h)
void Continue(Handle h); // makes any thread blocked in Wait(h) continue
struct S {
  int i;
  void foo() {
    i = 23; // <- sample code that uses "this" pointer
    Continue(insideFoo); // <- signal main that we are inside S::foo and past all "this" usage
    Wait(continueFoo); // <- block until main tells us to continue
    // here, "this" is destroyed (see main function)
    if (b) return; // <- b is not instance variable, so its not an access to dangling "this"
    i = 42; // <- other sample code that uses "this" pointer
  }
};
int main() {
  S* s = new S;
  continueFoo.lock();
  std::thread t(std::bind(&S::foo, s));
  Wait(insideFoo); // wait until S::foo is finished accessing "this"
  delete s;
  b = false;
  Continue(continueFoo); // let s.foo continue.
}
The question is about the fact that S::foo already started and is guaranteed to be at an instruction inside the function that does not access the this pointer anymore. Also, this "instruction inside foo()" is protected by a memory fence (std::mutex in my example here). The code that follows if(b) is also fenced (by the fact that b is a std::atomic<bool>), right?
To me, it still feels kind of fishy to return to a member function whose this-pointer is dangling, but I can't find any reason why this should be explicitly "undefined behaviour". Its not accessing s->foo() (because the function already started) and the immediate return after the check to b guarantees that no other this-access happens.
So is this allowed? Is purely returning from a subfunction (Wait(continueFoo) in this case) into a member-function whose this is dangling already undefined behaviour? I could not find any reference in the standard to that.
PS: This is a second attempt on my (poorly explained) question at Undefined behaviour to delete "this" when other thread is running member function that does not access "this"?. I don't think its the same question as the linked Is this undefined behaviour in C++ calling a function from a dangling pointer because I am not dereferencing s after its deleted. I am explicitly first calling s->foo and then deleting the instance (and I guarantee that the thread already started).
 
     
    