if (parm_i->this_ptr || parm_i->lambda_cobj)
{
/* We pass a reference to *this to the allocator lookup. */
- tree tt = TREE_TYPE (TREE_TYPE (arg));
- tree this_ref = build1 (INDIRECT_REF, tt, arg);
- tt = cp_build_reference_type (tt, false);
- this_ref = convert_to_reference (tt, this_ref, CONV_STATIC,
- LOOKUP_NORMAL , NULL_TREE,
- tf_warning_or_error);
- vec_safe_push (args, convert_from_reference (this_ref));
+ tree this_ref = cp_build_fold_indirect_ref (arg);
+ vec_safe_push (args, this_ref);
}
else
vec_safe_push (args, convert_from_reference (arg));
if (parm.this_ptr || parm.lambda_cobj)
{
/* We pass a reference to *this to the param preview. */
- tree tt = TREE_TYPE (arg);
- gcc_checking_assert (POINTER_TYPE_P (tt));
- tree ct = TREE_TYPE (tt);
- tree this_ref = build1 (INDIRECT_REF, ct, arg);
- tree rt = cp_build_reference_type (ct, false);
- this_ref = convert_to_reference (rt, this_ref, CONV_STATIC,
- LOOKUP_NORMAL, NULL_TREE,
- tf_warning_or_error);
+ tree this_ref = cp_build_fold_indirect_ref (arg);
vec_safe_push (promise_args, this_ref);
}
else if (parm.rv_ref)
--- /dev/null
+// PR c++/104981 - ICE from convert_to_base when passing *this to promise ctor
+
+#include <coroutine>
+
+class Base {};
+
+struct PromiseType;
+
+struct Result {
+ using promise_type = PromiseType;
+};
+
+struct PromiseType {
+ PromiseType(const Base& parser, auto&&...) {}
+
+ Result get_return_object() { return {}; }
+
+ static std::suspend_never initial_suspend() { return {}; }
+ static std::suspend_always final_suspend() noexcept { return {}; }
+ [[noreturn]] static void unhandled_exception() { throw; }
+
+ void return_value(int) {}
+};
+
+struct Derived : Base {
+ Result f() {
+ co_return 42;
+ }
+};
+
+int main() {
+ Derived d;
+ d.f();
+}
--- /dev/null
+// PR c++/115550 - wrong deduction when passing *this to promise ctor template
+
+#include <coroutine>
+
+template <typename T> struct remove_reference { using type = T; };
+template <typename T> struct remove_reference<T&> { using type = T; };
+template <typename T> struct remove_reference<T&&> { using type = T; };
+template <typename T> using remove_reference_t = remove_reference<T>::type;
+
+template <typename, typename>
+struct is_same { static inline constexpr bool value = false; };
+template <typename T>
+struct is_same<T, T> { static inline constexpr bool value = true; };
+
+template <typename T, typename U>
+concept same_as = is_same<T, U>::value;
+
+struct coroutine
+{
+ struct promise_type
+ {
+ template <typename Arg>
+ explicit promise_type(Arg&&)
+ {
+ static_assert(same_as<
+ remove_reference_t<remove_reference_t<Arg>>,
+ remove_reference_t<Arg>
+ >);
+ }
+
+ coroutine get_return_object() { return {}; }
+
+ std::suspend_never initial_suspend() noexcept { return {}; }
+ std::suspend_never final_suspend() noexcept { return {}; }
+
+ void return_void() {}
+ void unhandled_exception() {throw;}
+ };
+};
+
+struct x
+{
+ coroutine f()
+ {
+ co_return;
+ }
+};