Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[clang-tidy] Add check
readability-avoid-return-with-void-value
(#7…
- Loading branch information
1 parent
f74ce00
commit a89141f
Showing
8 changed files
with
232 additions
and
0 deletions.
There are no files selected for viewing
57 changes: 57 additions & 0 deletions
57
clang-tools-extra/clang-tidy/readability/AvoidReturnWithVoidValueCheck.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
//===--- AvoidReturnWithVoidValueCheck.cpp - clang-tidy -------------------===// | ||
// | ||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
// See https://llvm.org/LICENSE.txt for license information. | ||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#include "AvoidReturnWithVoidValueCheck.h" | ||
#include "clang/AST/Stmt.h" | ||
#include "clang/ASTMatchers/ASTMatchFinder.h" | ||
#include "clang/ASTMatchers/ASTMatchers.h" | ||
|
||
using namespace clang::ast_matchers; | ||
|
||
namespace clang::tidy::readability { | ||
|
||
static constexpr auto IgnoreMacrosName = "IgnoreMacros"; | ||
static constexpr auto IgnoreMacrosDefault = true; | ||
|
||
static constexpr auto StrictModeName = "StrictMode"; | ||
static constexpr auto StrictModeDefault = true; | ||
|
||
AvoidReturnWithVoidValueCheck::AvoidReturnWithVoidValueCheck( | ||
StringRef Name, ClangTidyContext *Context) | ||
: ClangTidyCheck(Name, Context), | ||
IgnoreMacros( | ||
Options.getLocalOrGlobal(IgnoreMacrosName, IgnoreMacrosDefault)), | ||
StrictMode(Options.getLocalOrGlobal(StrictModeName, StrictModeDefault)) {} | ||
|
||
void AvoidReturnWithVoidValueCheck::registerMatchers(MatchFinder *Finder) { | ||
Finder->addMatcher( | ||
returnStmt( | ||
hasReturnValue(allOf(hasType(voidType()), unless(initListExpr()))), | ||
optionally(hasParent(compoundStmt().bind("compound_parent")))) | ||
.bind("void_return"), | ||
this); | ||
} | ||
|
||
void AvoidReturnWithVoidValueCheck::check( | ||
const MatchFinder::MatchResult &Result) { | ||
const auto *VoidReturn = Result.Nodes.getNodeAs<ReturnStmt>("void_return"); | ||
if (IgnoreMacros && VoidReturn->getBeginLoc().isMacroID()) | ||
return; | ||
if (!StrictMode && !Result.Nodes.getNodeAs<CompoundStmt>("compound_parent")) | ||
return; | ||
diag(VoidReturn->getBeginLoc(), "return statement within a void function " | ||
"should not have a specified return value"); | ||
} | ||
|
||
void AvoidReturnWithVoidValueCheck::storeOptions( | ||
ClangTidyOptions::OptionMap &Opts) { | ||
Options.store(Opts, IgnoreMacrosName, IgnoreMacros); | ||
Options.store(Opts, StrictModeName, StrictMode); | ||
} | ||
|
||
} // namespace clang::tidy::readability |
44 changes: 44 additions & 0 deletions
44
clang-tools-extra/clang-tidy/readability/AvoidReturnWithVoidValueCheck.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
//===--- AvoidReturnWithVoidValueCheck.h - clang-tidy -----------*- C++ -*-===// | ||
// | ||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
// See https://llvm.org/LICENSE.txt for license information. | ||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_AVOIDRETURNWITHVOIDVALUECHECK_H | ||
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_AVOIDRETURNWITHVOIDVALUECHECK_H | ||
|
||
#include "../ClangTidyCheck.h" | ||
|
||
namespace clang::tidy::readability { | ||
|
||
/// Finds return statements with `void` values used within functions with `void` | ||
/// result types. | ||
/// | ||
/// For the user-facing documentation see: | ||
/// http://clang.llvm.org/extra/clang-tidy/checks/readability/avoid-return-with-void-value.html | ||
class AvoidReturnWithVoidValueCheck : public ClangTidyCheck { | ||
public: | ||
AvoidReturnWithVoidValueCheck(StringRef Name, ClangTidyContext *Context); | ||
|
||
void registerMatchers(ast_matchers::MatchFinder *Finder) override; | ||
void check(const ast_matchers::MatchFinder::MatchResult &Result) override; | ||
|
||
private: | ||
std::optional<TraversalKind> getCheckTraversalKind() const override { | ||
return TK_IgnoreUnlessSpelledInSource; | ||
} | ||
bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { | ||
return LangOpts.CPlusPlus; | ||
} | ||
void storeOptions(ClangTidyOptions::OptionMap &Opts) override; | ||
|
||
private: | ||
bool IgnoreMacros; | ||
bool StrictMode; | ||
}; | ||
|
||
} // namespace clang::tidy::readability | ||
|
||
#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_AVOIDRETURNWITHVOIDVALUECHECK_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
51 changes: 51 additions & 0 deletions
51
...tools-extra/docs/clang-tidy/checks/readability/avoid-return-with-void-value.rst
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
.. title:: clang-tidy - readability-avoid-return-with-void-value | ||
|
||
readability-avoid-return-with-void-value | ||
======================================== | ||
|
||
Finds return statements with ``void`` values used within functions with | ||
``void`` result types. | ||
|
||
A function with a ``void`` return type is intended to perform a task without | ||
producing a return value. Return statements with expressions could lead | ||
to confusion and may miscommunicate the function's intended behavior. | ||
|
||
Example: | ||
|
||
.. code-block:: | ||
void g(); | ||
void f() { | ||
// ... | ||
return g(); | ||
} | ||
In a long function body, the ``return`` statement suggests that the function | ||
returns a value. However, ``return g();`` is a combination of two statements | ||
that should be written as | ||
|
||
.. code-block:: | ||
g(); | ||
return; | ||
to make clear that ``g()`` is called and immediately afterwards the function | ||
returns (nothing). | ||
|
||
In C, the same issue is detected by the compiler if the ``-Wpedantic`` mode | ||
is enabled. | ||
|
||
Options | ||
------- | ||
|
||
.. option:: IgnoreMacros | ||
|
||
The value `false` specifies that return statements expanded | ||
from macros are not checked. The default value is `true`. | ||
|
||
.. option:: StrictMode | ||
|
||
The value `false` specifies that a direct return statement shall | ||
be excluded from the analysis if it is the only statement not | ||
contained in a block like ``if (cond) return g();``. The default | ||
value is `true`. |
69 changes: 69 additions & 0 deletions
69
clang-tools-extra/test/clang-tidy/checkers/readability/avoid-return-with-void-value.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
// RUN: %check_clang_tidy %s readability-avoid-return-with-void-value %t | ||
// RUN: %check_clang_tidy -check-suffixes=,INCLUDE-MACROS %s readability-avoid-return-with-void-value %t \ | ||
// RUN: -- -config="{CheckOptions: [{key: readability-avoid-return-with-void-value.IgnoreMacros, value: false}]}" \ | ||
// RUN: -- | ||
// RUN: %check_clang_tidy -check-suffixes=LENIENT %s readability-avoid-return-with-void-value %t \ | ||
// RUN: -- -config="{CheckOptions: [{key: readability-avoid-return-with-void-value.StrictMode, value: false}]}" \ | ||
// RUN: -- | ||
|
||
void f1(); | ||
|
||
void f2() { | ||
return f1(); | ||
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: return statement within a void function should not have a specified return value [readability-avoid-return-with-void-value] | ||
// CHECK-MESSAGES-LENIENT: :[[@LINE-2]]:5: warning: return statement within a void function should not have a specified return value [readability-avoid-return-with-void-value] | ||
} | ||
|
||
void f3(bool b) { | ||
if (b) return f1(); | ||
// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: return statement within a void function should not have a specified return value [readability-avoid-return-with-void-value] | ||
return f2(); | ||
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: return statement within a void function should not have a specified return value [readability-avoid-return-with-void-value] | ||
// CHECK-MESSAGES-LENIENT: :[[@LINE-2]]:5: warning: return statement within a void function should not have a specified return value [readability-avoid-return-with-void-value] | ||
} | ||
|
||
template<class T> | ||
T f4() {} | ||
|
||
void f5() { | ||
return f4<void>(); | ||
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: return statement within a void function should not have a specified return value [readability-avoid-return-with-void-value] | ||
// CHECK-MESSAGES-LENIENT: :[[@LINE-2]]:5: warning: return statement within a void function should not have a specified return value [readability-avoid-return-with-void-value] | ||
} | ||
|
||
void f6() { return; } | ||
|
||
int f7() { return 1; } | ||
|
||
int f8() { return f7(); } | ||
|
||
void f9() { | ||
return (void)f7(); | ||
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: return statement within a void function should not have a specified return value [readability-avoid-return-with-void-value] | ||
// CHECK-MESSAGES-LENIENT: :[[@LINE-2]]:5: warning: return statement within a void function should not have a specified return value [readability-avoid-return-with-void-value] | ||
} | ||
|
||
#define RETURN_VOID return (void)1 | ||
|
||
void f10() { | ||
RETURN_VOID; | ||
// CHECK-MESSAGES-INCLUDE-MACROS: :[[@LINE-1]]:5: warning: return statement within a void function should not have a specified return value [readability-avoid-return-with-void-value] | ||
} | ||
|
||
template <typename A> | ||
struct C { | ||
C(A) {} | ||
}; | ||
|
||
template <class T> | ||
C<T> f11() { return {}; } | ||
|
||
using VOID = void; | ||
|
||
VOID f12(); | ||
|
||
VOID f13() { | ||
return f12(); | ||
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: return statement within a void function should not have a specified return value [readability-avoid-return-with-void-value] | ||
// CHECK-MESSAGES-LENIENT: :[[@LINE-2]]:5: warning: return statement within a void function should not have a specified return value [readability-avoid-return-with-void-value] | ||
} |