Skip to content

Commit 531a5c0

Browse files
committed
Address review comments, and add a test
1 parent e98da0e commit 531a5c0

File tree

2 files changed

+27
-16
lines changed

2 files changed

+27
-16
lines changed

clang/lib/Analysis/ReachableCode.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -455,7 +455,7 @@ bool DeadCodeScan::isDeadCodeRoot(const clang::CFGBlock *Block) {
455455
}
456456

457457
// Check if the given `DeadStmt` is a coroutine statement and is a substmt of
458-
// the coroutine statement.
458+
// the coroutine statement. `Block` is the CFGBlock containing the `DeadStmt`.
459459
static bool isInCoroutineStmt(const Stmt* DeadStmt, const CFGBlock *Block) {
460460
// The coroutine statement, co_return, co_await, or co_yield.
461461
const Stmt* CoroStmt = nullptr;
@@ -468,20 +468,20 @@ static bool isInCoroutineStmt(const Stmt* DeadStmt, const CFGBlock *Block) {
468468
if (S == DeadStmt)
469469
AfterDeadStmt = true;
470470
if (AfterDeadStmt &&
471+
// For simplicity, we only check simple coroutine statements.
471472
(llvm::isa<CoreturnStmt>(S) || llvm::isa<CoroutineSuspendExpr>(S))) {
472473
CoroStmt = S;
473474
break;
474475
}
475476
}
476477
if (!CoroStmt)
477478
return false;
478-
479479
struct Checker : RecursiveASTVisitor<Checker> {
480-
const Stmt *StmtToCheck;
480+
const Stmt *DeadStmt;
481481
bool CoroutineSubStmt = false;
482-
Checker(const Stmt *S) : StmtToCheck(S) {}
482+
Checker(const Stmt *S) : DeadStmt(S) {}
483483
bool VisitStmt(const Stmt *S) {
484-
if (S == StmtToCheck)
484+
if (S == DeadStmt)
485485
CoroutineSubStmt = true;
486486
return true;
487487
}

clang/test/SemaCXX/coroutine-unreachable-warning.cpp

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
#include "Inputs/std-coroutine.h"
44

5-
extern void abort (void) __attribute__ ((__noreturn__));
5+
extern void abort(void) __attribute__((__noreturn__));
66

77
struct task {
88
struct promise_type {
@@ -12,6 +12,13 @@ struct task {
1212
std::suspend_always yield_value(int) { return {}; }
1313
task get_return_object();
1414
void unhandled_exception();
15+
16+
struct Awaiter {
17+
bool await_ready();
18+
void await_suspend(auto);
19+
int await_resume();
20+
};
21+
auto await_transform(const int& x) { return Awaiter{}; }
1522
};
1623
};
1724

@@ -22,7 +29,7 @@ task test1() {
2229

2330
task test2() {
2431
abort();
25-
1; // expected-warning {{code will never be executed}}
32+
1; // expected-warning {{code will never be executed}}
2633
co_yield 1;
2734
}
2835

@@ -33,33 +40,37 @@ task test3() {
3340

3441
task test4() {
3542
abort();
36-
1; // expected-warning {{code will never be executed}}
43+
1; // expected-warning {{code will never be executed}}
3744
co_return;
3845
}
3946

40-
4147
task test5() {
4248
abort();
43-
co_await std::suspend_never{};
49+
co_await 1;
4450
}
4551

4652
task test6() {
4753
abort();
48-
1; // expected-warning {{code will never be executed}}
49-
co_await std::suspend_never{};
54+
1; // expected-warning {{code will never be executed}}
55+
co_await 3;
5056
}
5157

5258
task test7() {
5359
// coroutine statements are not considered unreachable.
54-
co_await std::suspend_never{};
60+
co_await 1;
5561
abort();
56-
co_await std::suspend_never{};
62+
co_await 2;
5763
}
5864

5965
task test8() {
6066
// coroutine statements are not considered unreachable.
61-
// co_await std::suspend_never{};
6267
abort();
6368
co_return;
64-
1 + 1; // expected-warning {{code will never be executed}}
69+
1 + 1; // expected-warning {{code will never be executed}}
70+
}
71+
72+
task test9() {
73+
abort();
74+
// This warning is emit on the declaration itself, rather the coroutine substmt.
75+
int x = co_await 1; // expected-warning {{code will never be executed}}
6576
}

0 commit comments

Comments
 (0)