diff options
author | Iain Sandoe <iain@sandoe.co.uk> | 2020-06-10 00:15:28 +0100 |
---|---|---|
committer | Iain Sandoe <iain@sandoe.co.uk> | 2020-06-10 20:02:45 +0100 |
commit | a9eec9625ea7165292958be04899b057804192fb (patch) | |
tree | 5ece325dccfd3d12ba7854207de18b21bb2a1451 | |
parent | a2c2cee92e5defff9bf23d3b1184ee96e57e5fdd (diff) | |
download | gcc-a9eec9625ea7165292958be04899b057804192fb.zip gcc-a9eec9625ea7165292958be04899b057804192fb.tar.gz gcc-a9eec9625ea7165292958be04899b057804192fb.tar.bz2 |
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.
-rw-r--r-- | gcc/cp/call.c | 4 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/coroutines/pr95440.C | 39 |
2 files changed, 41 insertions, 2 deletions
diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 3c97b98..b99959f 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -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); diff --git a/gcc/testsuite/g++.dg/coroutines/pr95440.C b/gcc/testsuite/g++.dg/coroutines/pr95440.C new file mode 100644 index 0000000..8542880 --- /dev/null +++ b/gcc/testsuite/g++.dg/coroutines/pr95440.C @@ -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() {} |