Skip to content

Commit b99fe4b

Browse files
committed
[clang-tidy] Add fix-its to avoid-return-with-void-value check
1 parent 536d78c commit b99fe4b

File tree

3 files changed

+41
-8
lines changed

3 files changed

+41
-8
lines changed

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

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,17 @@
1010
#include "clang/AST/Stmt.h"
1111
#include "clang/ASTMatchers/ASTMatchFinder.h"
1212
#include "clang/ASTMatchers/ASTMatchers.h"
13+
#include "clang/Lex/Lexer.h"
1314

1415
using namespace clang::ast_matchers;
1516

1617
namespace clang::tidy::readability {
1718

18-
static constexpr auto IgnoreMacrosName = "IgnoreMacros";
19-
static constexpr auto IgnoreMacrosDefault = true;
19+
static constexpr char IgnoreMacrosName[] = "IgnoreMacros";
20+
static const bool IgnoreMacrosDefault = true;
2021

21-
static constexpr auto StrictModeName = "StrictMode";
22-
static constexpr auto StrictModeDefault = true;
22+
static constexpr char StrictModeName[] = "StrictMode";
23+
static const bool StrictModeDefault = true;
2324

2425
AvoidReturnWithVoidValueCheck::AvoidReturnWithVoidValueCheck(
2526
StringRef Name, ClangTidyContext *Context)
@@ -42,10 +43,28 @@ void AvoidReturnWithVoidValueCheck::check(
4243
const auto *VoidReturn = Result.Nodes.getNodeAs<ReturnStmt>("void_return");
4344
if (IgnoreMacros && VoidReturn->getBeginLoc().isMacroID())
4445
return;
45-
if (!StrictMode && !Result.Nodes.getNodeAs<CompoundStmt>("compound_parent"))
46+
const auto *SurroundingBlock =
47+
Result.Nodes.getNodeAs<CompoundStmt>("compound_parent");
48+
if (!StrictMode && !SurroundingBlock)
4649
return;
50+
const StringRef ReturnExpr =
51+
Lexer::getSourceText(CharSourceRange::getTokenRange(
52+
VoidReturn->getRetValue()->getSourceRange()),
53+
*Result.SourceManager, getLangOpts());
54+
SourceLocation SemicolonPos;
55+
if (const std::optional<Token> NextToken =
56+
Lexer::findNextToken(VoidReturn->getRetValue()->getEndLoc(),
57+
*Result.SourceManager, getLangOpts()))
58+
SemicolonPos = NextToken->getEndLoc();
59+
std::string Replacement = (ReturnExpr + "; return;").str();
60+
if (!SurroundingBlock)
61+
Replacement = "{" + Replacement + "}";
4762
diag(VoidReturn->getBeginLoc(), "return statement within a void function "
48-
"should not have a specified return value");
63+
"should not have a specified return value")
64+
<< FixItHint::CreateReplacement(
65+
CharSourceRange::getTokenRange(VoidReturn->getBeginLoc(),
66+
SemicolonPos),
67+
Replacement);
4968
}
5069

5170
void AvoidReturnWithVoidValueCheck::storeOptions(

clang-tools-extra/docs/ReleaseNotes.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,10 @@ Changes in existing checks
174174
<clang-tidy/checks/modernize/use-override>` check to also remove any trailing
175175
whitespace when deleting the ``virtual`` keyword.
176176

177+
- Improved :doc:`readability-avoid-return-with-void-value
178+
<clang-tidy/checks/readability/avoid-return-with-void-value>` check by adding
179+
fix-its.
180+
177181
- Improved :doc:`readability-implicit-bool-conversion
178182
<clang-tidy/checks/readability/implicit-bool-conversion>` check to provide
179183
valid fix suggestions for ``static_cast`` without a preceding space and

clang-tools-extra/test/clang-tidy/checkers/readability/avoid-return-with-void-value.cpp

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,18 @@ void f2() {
1212
return f1();
1313
// 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]
1414
// 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]
15+
// CHECK-FIXES: f1(); return;
1516
}
1617

1718
void f3(bool b) {
1819
if (b) return f1();
1920
// 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]
21+
// CHECK-FIXES: if (b) {f1(); return;}
2022
return f2();
2123
// 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]
2224
// 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]
25+
// CHECK-FIXES: f2(); return;
26+
// CHECK-FIXES-LENIENT: f2(); return;
2327
}
2428

2529
template<class T>
@@ -29,6 +33,8 @@ void f5() {
2933
return f4<void>();
3034
// 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]
3135
// 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]
36+
// CHECK-FIXES: f4<void>(); return;
37+
// CHECK-FIXES-LENIENT: f4<void>(); return;
3238
}
3339

3440
void f6() { return; }
@@ -41,6 +47,8 @@ void f9() {
4147
return (void)f7();
4248
// 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]
4349
// 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]
50+
// CHECK-FIXES: (void)f7(); return;
51+
// CHECK-FIXES-LENIENT: (void)f7(); return;
4452
}
4553

4654
#define RETURN_VOID return (void)1
@@ -50,12 +58,12 @@ void f10() {
5058
// 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]
5159
}
5260

53-
template <typename A>
61+
template <typename A>
5462
struct C {
5563
C(A) {}
5664
};
5765

58-
template <class T>
66+
template <class T>
5967
C<T> f11() { return {}; }
6068

6169
using VOID = void;
@@ -66,4 +74,6 @@ VOID f13() {
6674
return f12();
6775
// 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]
6876
// 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]
77+
// CHECK-FIXES: f12(); return;
78+
// CHECK-FIXES-LENIENT: f12(); return;
6979
}

0 commit comments

Comments
 (0)