[Refactoring] Don't drop returns with expressions

Previously we were unconditionally dropping a
return statement if it was the last node, which
could cause us to inadvertently drop the result
expression as well. Instead, only drop bare
'return' statements.

rdar://77789360
This commit is contained in:
Hamish Knight
2021-05-14 11:17:59 +01:00
parent aa189f2fe9
commit 7ab5915750
2 changed files with 37 additions and 6 deletions

View File

@@ -4623,16 +4623,24 @@ public:
!Nodes.back().isImplicit();
}
/// If the last recorded node is an explicit return or break statement, drop
/// it from the list.
void dropTrailingReturnOrBreak() {
/// If the last recorded node is an explicit return or break statement that
/// can be safely dropped, drop it from the list.
void dropTrailingReturnOrBreakIfPossible() {
if (!hasTrailingReturnOrBreak())
return;
auto *Node = Nodes.back().get<Stmt *>();
// If this is a return statement with return expression, let's preserve it.
if (auto *RS = dyn_cast<ReturnStmt>(Node)) {
if (RS->hasResult())
return;
}
// Remove the node from the list, but make sure to add it as a possible
// comment loc to preserve any of its attached comments.
auto Node = Nodes.pop_back_val();
addPossibleCommentLoc(Node.getStartLoc());
Nodes.pop_back();
addPossibleCommentLoc(Node->getStartLoc());
}
/// Returns a list of nodes to print in a brace statement. This picks up the
@@ -4895,7 +4903,7 @@ private:
NodesToPrint Nodes) {
if (Nodes.hasTrailingReturnOrBreak()) {
CurrentBlock = OtherBlock;
Nodes.dropTrailingReturnOrBreak();
Nodes.dropTrailingReturnOrBreakIfPossible();
Block->addAllNodes(std::move(Nodes));
} else {
Block->addAllNodes(std::move(Nodes));