[clang-tools-extra] r344785 - [clang-tidy] Resolve readability-else-after-return false positive for constexpr if.
Marek Kurdej via cfe-commits
cfe-commits at lists.llvm.org
Fri Oct 19 08:26:17 PDT 2018
Author: mkurdej
Date: Fri Oct 19 08:26:17 2018
New Revision: 344785
URL: http://llvm.org/viewvc/llvm-project?rev=344785&view=rev
Log:
[clang-tidy] Resolve readability-else-after-return false positive for constexpr if.
Summary:
It fixes the false positive when using constexpr if and where else cannot be removed:
Example:
```
if constexpr (sizeof(int) > 4)
// ...
return /* ... */;
else // This else cannot be removed.
// ...
return /* ... */;
```
Reviewers: alexfh, aaron.ballman
Reviewed By: aaron.ballman
Subscribers: lebedev.ri, xazax.hun, cfe-commits
Differential Revision: https://reviews.llvm.org/D53372
Added:
clang-tools-extra/trunk/test/clang-tidy/readability-else-after-return-if-constexpr.cpp
Modified:
clang-tools-extra/trunk/clang-tidy/readability/ElseAfterReturnCheck.cpp
Modified: clang-tools-extra/trunk/clang-tidy/readability/ElseAfterReturnCheck.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/readability/ElseAfterReturnCheck.cpp?rev=344785&r1=344784&r2=344785&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/readability/ElseAfterReturnCheck.cpp (original)
+++ clang-tools-extra/trunk/clang-tidy/readability/ElseAfterReturnCheck.cpp Fri Oct 19 08:26:17 2018
@@ -1,57 +1,58 @@
-//===--- ElseAfterReturnCheck.cpp - clang-tidy-----------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "ElseAfterReturnCheck.h"
-#include "clang/AST/ASTContext.h"
-#include "clang/ASTMatchers/ASTMatchFinder.h"
-#include "clang/Tooling/FixIt.h"
-
-using namespace clang::ast_matchers;
-
-namespace clang {
-namespace tidy {
-namespace readability {
-
-void ElseAfterReturnCheck::registerMatchers(MatchFinder *Finder) {
- const auto ControlFlowInterruptorMatcher =
- stmt(anyOf(returnStmt().bind("return"), continueStmt().bind("continue"),
- breakStmt().bind("break"),
- expr(ignoringImplicit(cxxThrowExpr().bind("throw")))));
- Finder->addMatcher(
- compoundStmt(forEach(
- ifStmt(hasThen(stmt(
- anyOf(ControlFlowInterruptorMatcher,
- compoundStmt(has(ControlFlowInterruptorMatcher))))),
- hasElse(stmt().bind("else")))
- .bind("if"))),
- this);
-}
-
-void ElseAfterReturnCheck::check(const MatchFinder::MatchResult &Result) {
- const auto *If = Result.Nodes.getNodeAs<IfStmt>("if");
- SourceLocation ElseLoc = If->getElseLoc();
- std::string ControlFlowInterruptor;
- for (const auto *BindingName : {"return", "continue", "break", "throw"})
- if (Result.Nodes.getNodeAs<Stmt>(BindingName))
- ControlFlowInterruptor = BindingName;
-
- DiagnosticBuilder Diag = diag(ElseLoc, "do not use 'else' after '%0'")
- << ControlFlowInterruptor;
- Diag << tooling::fixit::createRemoval(ElseLoc);
-
- // FIXME: Removing the braces isn't always safe. Do a more careful analysis.
- // FIXME: Change clang-format to correctly un-indent the code.
- if (const auto *CS = Result.Nodes.getNodeAs<CompoundStmt>("else"))
- Diag << tooling::fixit::createRemoval(CS->getLBracLoc())
- << tooling::fixit::createRemoval(CS->getRBracLoc());
-}
-
-} // namespace readability
-} // namespace tidy
-} // namespace clang
+//===--- ElseAfterReturnCheck.cpp - clang-tidy-----------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "ElseAfterReturnCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Tooling/FixIt.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace tidy {
+namespace readability {
+
+void ElseAfterReturnCheck::registerMatchers(MatchFinder *Finder) {
+ const auto ControlFlowInterruptorMatcher =
+ stmt(anyOf(returnStmt().bind("return"), continueStmt().bind("continue"),
+ breakStmt().bind("break"),
+ expr(ignoringImplicit(cxxThrowExpr().bind("throw")))));
+ Finder->addMatcher(
+ compoundStmt(forEach(
+ ifStmt(unless(isConstexpr()),
+ hasThen(stmt(
+ anyOf(ControlFlowInterruptorMatcher,
+ compoundStmt(has(ControlFlowInterruptorMatcher))))),
+ hasElse(stmt().bind("else")))
+ .bind("if"))),
+ this);
+}
+
+void ElseAfterReturnCheck::check(const MatchFinder::MatchResult &Result) {
+ const auto *If = Result.Nodes.getNodeAs<IfStmt>("if");
+ SourceLocation ElseLoc = If->getElseLoc();
+ std::string ControlFlowInterruptor;
+ for (const auto *BindingName : {"return", "continue", "break", "throw"})
+ if (Result.Nodes.getNodeAs<Stmt>(BindingName))
+ ControlFlowInterruptor = BindingName;
+
+ DiagnosticBuilder Diag = diag(ElseLoc, "do not use 'else' after '%0'")
+ << ControlFlowInterruptor;
+ Diag << tooling::fixit::createRemoval(ElseLoc);
+
+ // FIXME: Removing the braces isn't always safe. Do a more careful analysis.
+ // FIXME: Change clang-format to correctly un-indent the code.
+ if (const auto *CS = Result.Nodes.getNodeAs<CompoundStmt>("else"))
+ Diag << tooling::fixit::createRemoval(CS->getLBracLoc())
+ << tooling::fixit::createRemoval(CS->getRBracLoc());
+}
+
+} // namespace readability
+} // namespace tidy
+} // namespace clang
Added: clang-tools-extra/trunk/test/clang-tidy/readability-else-after-return-if-constexpr.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/readability-else-after-return-if-constexpr.cpp?rev=344785&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/readability-else-after-return-if-constexpr.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/readability-else-after-return-if-constexpr.cpp Fri Oct 19 08:26:17 2018
@@ -0,0 +1,22 @@
+// RUN: %check_clang_tidy %s readability-else-after-return %t -- -- -std=c++17
+
+// Constexpr if is an exception to the rule, we cannot remove the else.
+void f() {
+ if (sizeof(int) > 4)
+ return;
+ else
+ return;
+ // CHECK-MESSAGES: [[@LINE-2]]:3: warning: do not use 'else' after 'return'
+
+ if constexpr (sizeof(int) > 4)
+ return;
+ else
+ return;
+
+ if constexpr (sizeof(int) > 4)
+ return;
+ else if constexpr (sizeof(long) > 4)
+ return;
+ else
+ return;
+}
More information about the cfe-commits
mailing list