Skip to content

Commit 4739176

Browse files
committed
[clang-tidy] Fix readability-simplify-boolean-expr crash with implicit cast in return.
Fixes llvm#55557 Reviewed By: LegalizeAdulthood Differential Revision: https://reviews.llvm.org/D125877
1 parent 46eef76 commit 4739176

File tree

3 files changed

+20
-42
lines changed

3 files changed

+20
-42
lines changed

clang-tools-extra/clang-tidy/readability/SimplifyBooleanExprCheck.cpp

Lines changed: 6 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -236,41 +236,6 @@ static std::string replacementExpression(const ASTContext &Context,
236236
return asBool(getText(Context, *E), NeedsStaticCast);
237237
}
238238

239-
static const Expr *stmtReturnsBool(const ReturnStmt *Ret, bool Negated) {
240-
if (const auto *Bool = dyn_cast<CXXBoolLiteralExpr>(Ret->getRetValue())) {
241-
if (Bool->getValue() == !Negated)
242-
return Bool;
243-
}
244-
if (const auto *Unary = dyn_cast<UnaryOperator>(Ret->getRetValue())) {
245-
if (Unary->getOpcode() == UO_LNot) {
246-
if (const auto *Bool =
247-
dyn_cast<CXXBoolLiteralExpr>(Unary->getSubExpr())) {
248-
if (Bool->getValue() == Negated)
249-
return Bool;
250-
}
251-
}
252-
}
253-
254-
return nullptr;
255-
}
256-
257-
static const Expr *stmtReturnsBool(const IfStmt *IfRet, bool Negated) {
258-
if (IfRet->getElse() != nullptr)
259-
return nullptr;
260-
261-
if (const auto *Ret = dyn_cast<ReturnStmt>(IfRet->getThen()))
262-
return stmtReturnsBool(Ret, Negated);
263-
264-
if (const auto *Compound = dyn_cast<CompoundStmt>(IfRet->getThen())) {
265-
if (Compound->size() == 1) {
266-
if (const auto *CompoundRet = dyn_cast<ReturnStmt>(Compound->body_back()))
267-
return stmtReturnsBool(CompoundRet, Negated);
268-
}
269-
}
270-
271-
return nullptr;
272-
}
273-
274239
static bool containsDiscardedTokens(const ASTContext &Context,
275240
CharSourceRange CharRange) {
276241
std::string ReplacementText =
@@ -502,8 +467,8 @@ class SimplifyBooleanExprCheck::Visitor : public RecursiveASTVisitor<Visitor> {
502467
if (Check->ChainedConditionalReturn ||
503468
(!PrevIf && If->getElse() == nullptr)) {
504469
Check->replaceCompoundReturnWithCondition(
505-
Context, cast<ReturnStmt>(*Second), TrailingReturnBool.Bool,
506-
If);
470+
Context, cast<ReturnStmt>(*Second), TrailingReturnBool.Bool, If,
471+
ThenReturnBool.Item);
507472
}
508473
}
509474
} else if (isa<LabelStmt, CaseStmt, DefaultStmt>(*First)) {
@@ -523,7 +488,7 @@ class SimplifyBooleanExprCheck::Visitor : public RecursiveASTVisitor<Visitor> {
523488
ThenReturnBool.Bool != TrailingReturnBool.Bool) {
524489
Check->replaceCompoundReturnWithCondition(
525490
Context, cast<ReturnStmt>(*Second), TrailingReturnBool.Bool,
526-
SubIf);
491+
SubIf, ThenReturnBool.Item);
527492
}
528493
}
529494
}
@@ -689,11 +654,11 @@ void SimplifyBooleanExprCheck::replaceWithReturnCondition(
689654

690655
void SimplifyBooleanExprCheck::replaceCompoundReturnWithCondition(
691656
const ASTContext &Context, const ReturnStmt *Ret, bool Negated,
692-
const IfStmt *If) {
693-
const auto *Lit = stmtReturnsBool(If, Negated);
657+
const IfStmt *If, const Expr *ThenReturn) {
694658
const std::string Replacement =
695659
"return " + replacementExpression(Context, Negated, If->getCond());
696-
issueDiag(Context, Lit->getBeginLoc(), SimplifyConditionalReturnDiagnostic,
660+
issueDiag(Context, ThenReturn->getBeginLoc(),
661+
SimplifyConditionalReturnDiagnostic,
697662
SourceRange(If->getBeginLoc(), Ret->getEndLoc()), Replacement);
698663
}
699664

clang-tools-extra/clang-tidy/readability/SimplifyBooleanExprCheck.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,8 @@ class SimplifyBooleanExprCheck : public ClangTidyCheck {
5555

5656
void replaceCompoundReturnWithCondition(const ASTContext &Context,
5757
const ReturnStmt *Ret, bool Negated,
58-
const IfStmt *If);
58+
const IfStmt *If,
59+
const Expr *ThenReturn);
5960

6061
void issueDiag(const ASTContext &Result, SourceLocation Loc,
6162
StringRef Description, SourceRange ReplacementRange,

clang-tools-extra/unittests/clang-tidy/ReadabilityModuleTest.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#include "ClangTidyTest.h"
33
#include "readability/BracesAroundStatementsCheck.h"
44
#include "readability/NamespaceCommentCheck.h"
5+
#include "readability/SimplifyBooleanExprCheck.h"
56
#include "gtest/gtest.h"
67

78
namespace clang {
@@ -10,6 +11,7 @@ namespace test {
1011

1112
using readability::BracesAroundStatementsCheck;
1213
using readability::NamespaceCommentCheck;
14+
using readability::SimplifyBooleanExprCheck;
1315
using namespace ast_matchers;
1416

1517
// Copied from ASTMatchersTests
@@ -533,6 +535,16 @@ TEST(BracesAroundStatementsCheckTest, ImplicitCastInReturn) {
533535
runCheckOnCode<BracesAroundStatementsCheck>(Input));
534536
}
535537

538+
TEST(SimplifyBooleanExprCheckTest, CodeWithError) {
539+
// Fixes PR55557
540+
// Need to downgrade Wreturn-type from error as runCheckOnCode will fatal_exit
541+
// if any errors occur.
542+
EXPECT_EQ("void foo(bool b){ return b; }",
543+
runCheckOnCode<SimplifyBooleanExprCheck>(
544+
"void foo(bool b){ if (b) return true; return false; }",
545+
nullptr, "input.cc", {"-Wno-error=return-type"}));
546+
}
547+
536548
} // namespace test
537549
} // namespace tidy
538550
} // namespace clang

0 commit comments

Comments
 (0)