Ensures that get_return_object's return type is the same as the return type for the function calling co_return. Otherwise, we try to construct an object, then free it, then return it.
Details
- Reviewers
ldionne • Quuxplusone - Group Reviewers
Restricted Project - Commits
- rG52123c96c016: [libcxx][nfc] Fix the ASAN bots: update expected.pass.cpp.
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
It would be great if someone who knows more about coroutines than I do looked over this (which is basically anyone because I know next to nothing). Basically it seems like we get the use-after-free error any time get_return_object returns something that is not the parent object and the parent object is not empty.
I have an intuition that this is related to https://bugs.llvm.org/show_bug.cgi?id=50369, which might not be fixed in reality. WDYT?
@ldionne I think it's unlikely that this has anything to do with shared_ptr. Below is a minimal reproducer that causes the same problem with the sanitizers. As you can see, there's no reference to shared_ptr, or any pointer. I think the new/delete that the bots are referencing is the new/delete that is used to create and deallocate the coroutine state (or maybe it's the promise... that might actually explain why it's trying to use the same memory).
// ADDITIONAL_COMPILE_FLAGS: -g -fsanitize=address #include <experimental/coroutine> #include <cassert> #include <memory> #include "test_macros.h" using namespace std::experimental; int x; struct tag { char data[8]; }; // `tag` can be any type. It could be empty, or an int, or anything. struct expected { char data; // No issues if this member isn't here. expected(tag) : data() {} struct promise_type { tag get_return_object() { return {}; } // No issues if we return an `expected` instead. suspend_never initial_suspend() { return {}; } suspend_never final_suspend() noexcept { return {}; } tag return_value(tag) { return tag{}; } void unhandled_exception() {} }; }; expected f1() { co_return {}; } int main(int, char**) { auto c1 = f1(); (void)c1; return 0; }
I have an intuition that this is related to https://bugs.llvm.org/show_bug.cgi?id=50369, which might not be fixed in reality. WDYT?
Also, that bug is fixed: https://godbolt.org/z/Ko138bn8a
They're either using too old a standard or too old of a compiler. Looks like someone already commented that, but I can investigate further and close the bug.
Thanks a lot for the reduction Zoe! Here's an ever so slightly more reduced Godbolt version: https://godbolt.org/z/oPK1PcPjT. Can you file a bug against Clang? Let's ship this to fix the CI.