aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIain Sandoe <iain@sandoe.co.uk>2020-06-10 00:15:28 +0100
committerIain Sandoe <iain@sandoe.co.uk>2020-06-10 20:02:45 +0100
commita9eec9625ea7165292958be04899b057804192fb (patch)
tree5ece325dccfd3d12ba7854207de18b21bb2a1451
parenta2c2cee92e5defff9bf23d3b1184ee96e57e5fdd (diff)
downloadgcc-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.c4
-rw-r--r--gcc/testsuite/g++.dg/coroutines/pr95440.C39
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() {}