coroutines: Make call argument handling more robust [PR95440]
build_new_method_call is supposed to be able to handle a null arguments list pointer (when the method has no parms). There were a couple of places where uses of the argument list pointer were not defended against NULL. gcc/cp/ChangeLog: PR c++/95440 * call.c (add_candidates): Use vec_safe_length() for testing the arguments list. (build_new_method_call_1): Use vec_safe_is_empty() when checking for an empty args list. gcc/testsuite/ChangeLog: PR c++/95440 * g++.dg/coroutines/pr95440.C: New test.
This commit is contained in:
parent
a2c2cee92e
commit
a9eec9625e
@ -5862,7 +5862,7 @@ add_candidates (tree fns, tree first_arg, const vec<tree, va_gc> *args,
|
||||
}
|
||||
|
||||
/* Don't bother reversing an operator with two identical parameters. */
|
||||
else if (args->length () == 2 && (flags & LOOKUP_REVERSED))
|
||||
else if (vec_safe_length (args) == 2 && (flags & LOOKUP_REVERSED))
|
||||
{
|
||||
tree parmlist = TYPE_ARG_TYPES (TREE_TYPE (fn));
|
||||
if (same_type_p (TREE_VALUE (parmlist),
|
||||
@ -10263,7 +10263,7 @@ build_new_method_call_1 (tree instance, tree fns, vec<tree, va_gc> **args,
|
||||
&& !(flags & LOOKUP_ONLYCONVERTING)
|
||||
&& cxx_dialect >= cxx20
|
||||
&& CP_AGGREGATE_TYPE_P (basetype)
|
||||
&& !user_args->is_empty ())
|
||||
&& !vec_safe_is_empty (user_args))
|
||||
{
|
||||
/* Create a CONSTRUCTOR from ARGS, e.g. {1, 2} from <1, 2>. */
|
||||
tree list = build_tree_list_vec (user_args);
|
||||
|
39
gcc/testsuite/g++.dg/coroutines/pr95440.C
Normal file
39
gcc/testsuite/g++.dg/coroutines/pr95440.C
Normal file
@ -0,0 +1,39 @@
|
||||
#if __has_include(<coroutine>)
|
||||
#include <coroutine>
|
||||
#else
|
||||
#include <experimental/coroutine>
|
||||
namespace std { using namespace experimental; }
|
||||
#endif
|
||||
#if 0
|
||||
struct suspend_n {
|
||||
const int x;
|
||||
constexpr suspend_n (int x) : x (x) {}
|
||||
constexpr static bool await_ready() { return false; }
|
||||
constexpr static void await_suspend(std::coroutine_handle<>) {}
|
||||
constexpr static void await_resume() {}
|
||||
};
|
||||
#endif
|
||||
struct task
|
||||
{
|
||||
struct promise_type
|
||||
{
|
||||
auto get_return_object() const { return task{}; }
|
||||
#if 0
|
||||
// static constexpr suspend_n initial_suspend() { return {2}; }
|
||||
#endif
|
||||
static constexpr std::suspend_always initial_suspend() { return {}; }
|
||||
static constexpr std::suspend_never final_suspend() { return {}; }
|
||||
static constexpr void return_void() {}
|
||||
static constexpr void unhandled_exception() {}
|
||||
};
|
||||
};
|
||||
|
||||
task
|
||||
test_task ()
|
||||
{
|
||||
co_await std::suspend_always{};
|
||||
}
|
||||
|
||||
auto t = test_task();
|
||||
|
||||
int main() {}
|
Loading…
Reference in New Issue
Block a user