Fix unused expression warning in co_await.
authorEric Fiselier <eric@efcs.ca>
Tue, 27 Mar 2018 00:58:16 +0000 (00:58 +0000)
committerEric Fiselier <eric@efcs.ca>
Tue, 27 Mar 2018 00:58:16 +0000 (00:58 +0000)
Previously, anytime the result of the resume expression in
operator co_await was unused, a warning was generated. This
patch fixes the issue by only generating the unused result warning
if calling `await_resume()` would also generate a warning.

llvm-svn: 328602

clang/lib/AST/Expr.cpp
clang/test/SemaCXX/coroutines.cpp

index 1813dfb..3cb0013 100644 (file)
@@ -2049,6 +2049,9 @@ bool Expr::isUnusedResultAWarning(const Expr *&WarnE, SourceLocation &Loc,
   case GenericSelectionExprClass:
     return cast<GenericSelectionExpr>(this)->getResultExpr()->
       isUnusedResultAWarning(WarnE, Loc, R1, R2, Ctx);
+  case CoawaitExprClass:
+    return cast<CoawaitExpr>(this)->getResumeExpr()->
+      isUnusedResultAWarning(WarnE, Loc, R1, R2, Ctx);
   case ChooseExprClass:
     return cast<ChooseExpr>(this)->getChosenSubExpr()->
       isUnusedResultAWarning(WarnE, Loc, R1, R2, Ctx);
index 6ceeb86..308e70e 100644 (file)
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++14 -fcoroutines-ts -verify %s -fcxx-exceptions -fexceptions
+// RUN: %clang_cc1 -std=c++14 -fcoroutines-ts -verify %s -fcxx-exceptions -fexceptions -Wunused-result
 
 void no_coroutine_traits_bad_arg_await() {
   co_await a; // expected-error {{include <experimental/coroutine>}}
@@ -1337,3 +1337,27 @@ bad_coroutine_calls_with_no_matching_constructor(int, int) {
 }
 
 } // namespace CoroHandleMemberFunctionTest
+
+
+class awaitable_no_unused_warn {
+public:
+  using handle_type = std::experimental::coroutine_handle<>;
+  constexpr bool await_ready()  { return false; }
+  void await_suspend(handle_type) noexcept {}
+  int await_resume() { return 1; }
+};
+
+
+class awaitable_unused_warn {
+public:
+  using handle_type = std::experimental::coroutine_handle<>;
+  constexpr bool await_ready()  { return false; }
+  void await_suspend(handle_type) noexcept {}
+  [[nodiscard]]
+  int await_resume() { return 1; }
+};
+
+void test_unused_warning() {
+  co_await awaitable_no_unused_warn();
+  co_await awaitable_unused_warn(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+}