-
Notifications
You must be signed in to change notification settings - Fork 11.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Incorrect promise constructor used with lambda coroutines #91983
Comments
@llvm/issue-subscribers-clang-frontend Author: Laura Andelare (landelare)
In the C++20 program below, the lambda has a non-static member operator(), but its object parameter is skipped when looking for a promise constructor overload. This results in the first overload being called, and an output of `Wrong`.
Tested on 18.1.5 and 19.0.0git (b5af667). When compiled with GCC or MSVC, the output is Additionally, removing the second constructor should make the resulting program no longer compile, which is the case with MSVC and GCC, but not Clang. #include <coroutine>
#include <iostream>
struct coro {};
struct promise {
promise(int) {std::cout << "Wrong\n";}
promise(auto, int){std::cout << "Correct\n";} // Remove me for an additional test case!
coro get_return_object() {return {};}
std::suspend_never initial_suspend() {return {};}
std::suspend_never final_suspend() noexcept {return {};}
void return_value(int) {}
void unhandled_exception() {}
};
template<typename... T>
struct std::coroutine_traits<coro, T...> {
using promise_type = promise;
};
int main() {
int x = 0;
[x](int y) -> coro { co_return x + y; }(1);
} |
@llvm/issue-subscribers-coroutines Author: Laura Andelare (landelare)
In the C++20 program below, the lambda has a non-static member operator(), but its object parameter is skipped when looking for a promise constructor overload. This results in the first overload being called, and an output of `Wrong`.
Tested on 18.1.5 and 19.0.0git (b5af667). When compiled with GCC or MSVC, the output is Additionally, removing the second constructor should make the resulting program no longer compile, which is the case with MSVC and GCC, but not Clang. #include <coroutine>
#include <iostream>
struct coro {};
struct promise {
promise(int) {std::cout << "Wrong\n";}
promise(auto, int){std::cout << "Correct\n";} // Remove me for an additional test case!
coro get_return_object() {return {};}
std::suspend_never initial_suspend() {return {};}
std::suspend_never final_suspend() noexcept {return {};}
void return_value(int) {}
void unhandled_exception() {}
};
template<typename... T>
struct std::coroutine_traits<coro, T...> {
using promise_type = promise;
};
int main() {
int x = 0;
[x](int y) -> coro { co_return x + y; }(1);
} |
It looks like this can be handled by #84519 |
In the C++20 program below, the lambda has a non-static member operator(), but its object parameter is skipped when looking for a promise constructor overload. This results in the first overload being called, and an output of
Wrong
.Tested on 18.1.5 and 19.0.0git (b5af667). When compiled with GCC or MSVC, the output is
Correct
, as expected.Additionally, removing the second constructor should make the resulting program no longer compile, which is the case with MSVC and GCC, but not Clang.
The text was updated successfully, but these errors were encountered: