On 6/10/20 4:43 PM, Iain Sandoe wrote:
Hi Jason,

Jason Merrill <ja...@redhat.com> wrote:

On Tue, Jun 9, 2020 at 5:04 AM Iain Sandoe <i...@sandoe.co.uk> wrote:


         /* Don't bother reversing an operator with two identical parameters.  
*/
-      else if (args->length () == 2 && (flags & LOOKUP_REVERSED))
+      else if (args && args->length () == 2 && (flags & LOOKUP_REVERSED))

The usual pattern is to use vec_safe_length here.  Similarly, in 
build_new_method_call_1 I think

!user_args->is_empty()

should be

vec_safe_is_empty (user_args)

Those changes are OK.

Thanks,

What I applied (after regtest on x86_64-linux/darwin and powerpc64-linux) is 
below.

Given that this fixes an IDE-on-valid filed against 10.1, I’d like to backport 
it for 10.2,
is that OK?

Yes.

thanks
Iain

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.
---
  gcc/cp/call.c                             |  4 +--
  gcc/testsuite/g++.dg/coroutines/pr95440.C | 39 +++++++++++++++++++++++
  2 files changed, 41 insertions(+), 2 deletions(-)
  create mode 100644 gcc/testsuite/g++.dg/coroutines/pr95440.C

diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 3c97b9846e2..b99959f76f9 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 00000000000..8542880d1ab
--- /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() {}


Reply via email to