summaryrefslogtreecommitdiff
path: root/test/SemaCXX/coreturn-eh.cpp
diff options
context:
space:
mode:
authorBrian Gesiak <modocache@gmail.com>2018-11-03 22:35:17 +0000
committerBrian Gesiak <modocache@gmail.com>2018-11-03 22:35:17 +0000
commita48feae49170188dabee14fdf9fe108c511d8e0e (patch)
tree28b819fc342f61ef548d633de6344c93324f284f /test/SemaCXX/coreturn-eh.cpp
parent6974b990e13dfb4190a6dffdcc8bac9edbd1cde5 (diff)
downloadclang-a48feae49170188dabee14fdf9fe108c511d8e0e.tar.gz
[coroutines] Fix fallthrough warning on try/catch
Summary: The test case added in this diff would incorrectly warn that control flow may fall through without returning. Here's a standalone example: https://godbolt.org/z/dCwXEi The same program, but using `return` instead of `co_return`, does not produce a warning: https://godbolt.org/z/mVldqQ The issue was in how Clang analysis would structure its representation of the control-flow graph. Specifically, when constructing the CFG, `CFGBuilder::Visit` had special handling of a `ReturnStmt`, in which it would place object destructors in the same CFG block as a `return` statement, immediately after it. Doing so would allow the logic in `lib/Sema/AnalysisBasedWarning.cpp` `CheckFallThrough` to work properly in the program that used `return`, correctly determining that no "plain edges" preceded the exit block of the function. Because a `co_return` statement would not enjoy the same treatment when it was being built into the control-flow graph, object destructors would not be placed in the same CFG block as the `co_return`, thus resulting in a "plain edge" preceding the exit block of the function, and so the warning logic would be triggered. Add special casing for `co_return` to Clang analysis, thereby remedying the mistaken warning. Test Plan: `check-clang` Reviewers: GorNishanov, tks2103, rsmith Reviewed By: GorNishanov Subscribers: EricWF, lewissbaker, cfe-commits Differential Revision: https://reviews.llvm.org/D54075 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@346074 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/SemaCXX/coreturn-eh.cpp')
-rw-r--r--test/SemaCXX/coreturn-eh.cpp45
1 files changed, 45 insertions, 0 deletions
diff --git a/test/SemaCXX/coreturn-eh.cpp b/test/SemaCXX/coreturn-eh.cpp
new file mode 100644
index 0000000000..79065736c0
--- /dev/null
+++ b/test/SemaCXX/coreturn-eh.cpp
@@ -0,0 +1,45 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 %s -std=c++14 -fcoroutines-ts -fcxx-exceptions -fsyntax-only -Wignored-qualifiers -Wno-error=return-type -verify -fblocks -Wall -Wextra -Wno-error=unreachable-code
+// expected-no-diagnostics
+
+#include "Inputs/std-coroutine.h"
+
+using std::experimental::suspend_always;
+using std::experimental::suspend_never;
+
+struct awaitable {
+ bool await_ready();
+ void await_suspend(std::experimental::coroutine_handle<>); // FIXME: coroutine_handle
+ void await_resume();
+} a;
+
+struct object { ~object() {} };
+
+struct promise_void_return_value {
+ void get_return_object();
+ suspend_always initial_suspend();
+ suspend_always final_suspend();
+ void unhandled_exception();
+ void return_value(object);
+};
+
+struct VoidTagReturnValue {
+ struct promise_type {
+ VoidTagReturnValue get_return_object();
+ suspend_always initial_suspend();
+ suspend_always final_suspend();
+ void unhandled_exception();
+ void return_value(object);
+ };
+};
+
+template <typename T1>
+struct std::experimental::coroutine_traits<void, T1> { using promise_type = promise_void_return_value; };
+
+VoidTagReturnValue test() {
+ object x = {};
+ try {
+ co_return {};
+ } catch (...) {
+ throw;
+ }
+}