Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[clang-tidy] Replace the usage of std::uncaught_exception with std::u…
…ncaught_exceptions Patch by: Daniel Kolozsvari! Differential Revision: https://reviews.llvm.org/D40787 llvm-svn: 325572
- Loading branch information
Showing
8 changed files
with
294 additions
and
0 deletions.
There are no files selected for viewing
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
104 changes: 104 additions & 0 deletions
104
clang-tools-extra/clang-tidy/modernize/UseUncaughtExceptionsCheck.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,104 @@ | ||
//===--- UseUncaughtExceptionsCheck.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 "UseUncaughtExceptionsCheck.h" | ||
#include "clang/AST/ASTContext.h" | ||
#include "clang/ASTMatchers/ASTMatchFinder.h" | ||
|
||
using namespace clang::ast_matchers; | ||
|
||
namespace clang { | ||
namespace tidy { | ||
namespace modernize { | ||
|
||
void UseUncaughtExceptionsCheck::registerMatchers(MatchFinder *Finder) { | ||
if (!getLangOpts().CPlusPlus17) | ||
return; | ||
|
||
std::string MatchText = "::std::uncaught_exception"; | ||
|
||
// Using declaration: warning and fix-it. | ||
Finder->addMatcher( | ||
usingDecl(hasAnyUsingShadowDecl(hasTargetDecl(hasName(MatchText)))) | ||
.bind("using_decl"), | ||
this); | ||
|
||
// DeclRefExpr: warning, no fix-it. | ||
Finder->addMatcher(declRefExpr(allOf(to(functionDecl(hasName(MatchText))), | ||
unless(callExpr()))) | ||
.bind("decl_ref_expr"), | ||
this); | ||
|
||
// CallExpr: warning, fix-it. | ||
Finder->addMatcher( | ||
callExpr(allOf(hasDeclaration(functionDecl(hasName(MatchText))), | ||
unless(hasAncestor(initListExpr())))) | ||
.bind("call_expr"), | ||
this); | ||
// CallExpr in initialisation list: warning, fix-it with avoiding narrowing | ||
// conversions. | ||
Finder->addMatcher( | ||
callExpr(allOf(hasAncestor(initListExpr()), | ||
hasDeclaration(functionDecl(hasName(MatchText))))) | ||
.bind("init_call_expr"), | ||
this); | ||
} | ||
|
||
void UseUncaughtExceptionsCheck::check(const MatchFinder::MatchResult &Result) { | ||
SourceLocation BeginLoc; | ||
SourceLocation EndLoc; | ||
const CallExpr *C = Result.Nodes.getNodeAs<CallExpr>("init_call_expr"); | ||
bool WarnOnly = false; | ||
|
||
if (C) { | ||
BeginLoc = C->getLocStart(); | ||
EndLoc = C->getLocEnd(); | ||
} else if (const auto *E = Result.Nodes.getNodeAs<CallExpr>("call_expr")) { | ||
BeginLoc = E->getLocStart(); | ||
EndLoc = E->getLocEnd(); | ||
} else if (const auto *D = | ||
Result.Nodes.getNodeAs<DeclRefExpr>("decl_ref_expr")) { | ||
BeginLoc = D->getLocStart(); | ||
EndLoc = D->getLocEnd(); | ||
WarnOnly = true; | ||
} else { | ||
const auto *U = Result.Nodes.getNodeAs<UsingDecl>("using_decl"); | ||
assert(U && "Null pointer, no node provided"); | ||
BeginLoc = U->getNameInfo().getBeginLoc(); | ||
EndLoc = U->getNameInfo().getEndLoc(); | ||
} | ||
|
||
auto Diag = diag(BeginLoc, "'std::uncaught_exception' is deprecated, use " | ||
"'std::uncaught_exceptions' instead"); | ||
|
||
if (!BeginLoc.isMacroID()) { | ||
StringRef Text = | ||
Lexer::getSourceText(CharSourceRange::getTokenRange(BeginLoc, EndLoc), | ||
*Result.SourceManager, getLangOpts()); | ||
|
||
Text.consume_back("()"); | ||
int TextLength = Text.size(); | ||
|
||
if (WarnOnly) { | ||
return; | ||
} | ||
|
||
if (!C) { | ||
Diag << FixItHint::CreateInsertion(BeginLoc.getLocWithOffset(TextLength), | ||
"s"); | ||
} else { | ||
Diag << FixItHint::CreateReplacement(C->getSourceRange(), | ||
"std::uncaught_exceptions() > 0"); | ||
} | ||
} | ||
} | ||
|
||
} // namespace modernize | ||
} // namespace tidy | ||
} // namespace clang |
37 changes: 37 additions & 0 deletions
37
clang-tools-extra/clang-tidy/modernize/UseUncaughtExceptionsCheck.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,37 @@ | ||
//===--- UseUncaughtExceptionsCheck.h - clang-tidy------------*- C++ -*-===// | ||
// | ||
// The LLVM Compiler Infrastructure | ||
// | ||
// This file is distributed under the University of Illinois Open Source | ||
// License. See LICENSE.TXT for details. | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_USE_UNCAUGHT_EXCEPTIONS_H | ||
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_USE_UNCAUGHT_EXCEPTIONS_H | ||
|
||
#include "../ClangTidy.h" | ||
|
||
namespace clang { | ||
namespace tidy { | ||
namespace modernize { | ||
|
||
/// This check will warn on calls to std::uncaught_exception and replace them with calls to | ||
/// std::uncaught_exceptions, since std::uncaught_exception was deprecated in C++17. In case of | ||
/// macro ID there will be only a warning without fixits. | ||
/// | ||
/// For the user-facing documentation see: | ||
/// http://clang.llvm.org/extra/clang-tidy/checks/modernize-use-uncaught-exceptions.html | ||
class UseUncaughtExceptionsCheck : public ClangTidyCheck { | ||
public: | ||
UseUncaughtExceptionsCheck(StringRef Name, ClangTidyContext *Context) | ||
: ClangTidyCheck(Name, Context) {} | ||
void registerMatchers(ast_matchers::MatchFinder *Finder) override; | ||
void check(const ast_matchers::MatchFinder::MatchResult &Result) override; | ||
}; | ||
|
||
} // namespace modernize | ||
} // namespace tidy | ||
} // namespace clang | ||
|
||
#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_USE_UNCAUGHT_EXCEPTIONS_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
64 changes: 64 additions & 0 deletions
64
clang-tools-extra/docs/clang-tidy/checks/modernize-use-uncaught-exceptions.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,64 @@ | ||
.. title:: clang-tidy - modernize-use-uncaught-exceptions | ||
|
||
modernize-use-uncaught-exceptions | ||
==================================== | ||
|
||
This check will warn on calls to ``std::uncaught_exception`` and replace them with | ||
calls to ``std::uncaught_exceptions``, since ``std::uncaught_exception`` was deprecated | ||
in C++17. | ||
|
||
Below are a few examples of what kind of occurrences will be found and what | ||
they will be replaced with. | ||
|
||
.. code-block:: c++ | ||
|
||
#define MACRO1 std::uncaught_exception | ||
#define MACRO2 std::uncaught_exception | ||
|
||
int uncaught_exception() { | ||
return 0; | ||
} | ||
|
||
int main() { | ||
int res; | ||
|
||
res = uncaught_exception(); | ||
// No warning, since it is not the deprecated function from namespace std | ||
|
||
res = MACRO2(); | ||
// Warning, but will not be replaced | ||
|
||
res = std::uncaught_exception(); | ||
// Warning and replaced | ||
|
||
using std::uncaught_exception; | ||
// Warning and replaced | ||
|
||
res = uncaught_exception(); | ||
// Warning and replaced | ||
} | ||
|
||
After applying the fixes the code will look like the following: | ||
|
||
.. code-block:: c++ | ||
|
||
#define MACRO1 std::uncaught_exception | ||
#define MACRO2 std::uncaught_exception | ||
|
||
int uncaught_exception() { | ||
return 0; | ||
} | ||
|
||
int main() { | ||
int res; | ||
|
||
res = uncaught_exception(); | ||
|
||
res = MACRO2(); | ||
|
||
res = std::uncaught_exceptions(); | ||
|
||
using std::uncaught_exceptions; | ||
|
||
res = uncaught_exceptions(); | ||
} |
79 changes: 79 additions & 0 deletions
79
clang-tools-extra/test/clang-tidy/modernize-use-uncaught-exceptions.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,79 @@ | ||
// RUN: %check_clang_tidy %s modernize-use-uncaught-exceptions %t -- -- -std=c++1z | ||
#define MACRO std::uncaught_exception | ||
// CHECK-FIXES: #define MACRO std::uncaught_exception | ||
|
||
bool uncaught_exception() { | ||
return 0; | ||
} | ||
|
||
namespace std { | ||
bool uncaught_exception() { | ||
return false; | ||
} | ||
|
||
int uncaught_exceptions() { | ||
return 0; | ||
} | ||
} | ||
|
||
template <typename T> | ||
bool doSomething(T t) { | ||
return t(); | ||
// CHECK-FIXES: return t(); | ||
} | ||
|
||
template <bool (*T)()> | ||
bool doSomething2() { | ||
return T(); | ||
// CHECK-MESSAGES: [[@LINE-1]]:10: warning: 'std::uncaught_exception' is deprecated, use 'std::uncaught_exceptions' instead | ||
// CHECK-FIXES: return T(); | ||
} | ||
|
||
void no_warn() { | ||
|
||
uncaught_exception(); | ||
// CHECK-FIXES: uncaught_exception(); | ||
|
||
doSomething(uncaught_exception); | ||
// CHECK-FIXES: doSomething(uncaught_exception); | ||
} | ||
|
||
void warn() { | ||
|
||
std::uncaught_exception(); | ||
// CHECK-MESSAGES: [[@LINE-1]]:3: warning: 'std::uncaught_exception' is deprecated, use 'std::uncaught_exceptions' instead | ||
// CHECK-FIXES: std::uncaught_exceptions(); | ||
|
||
using std::uncaught_exception; | ||
// CHECK-MESSAGES: [[@LINE-1]]:14: warning: 'std::uncaught_exception' is deprecated, use 'std::uncaught_exceptions' instead | ||
// CHECK-FIXES: using std::uncaught_exceptions; | ||
|
||
uncaught_exception(); | ||
// CHECK-MESSAGES: [[@LINE-1]]:3: warning: 'std::uncaught_exception' is deprecated, use 'std::uncaught_exceptions' instead | ||
// CHECK-FIXES: uncaught_exceptions(); | ||
|
||
bool b{uncaught_exception()}; | ||
// CHECK-MESSAGES: [[@LINE-1]]:10: warning: 'std::uncaught_exception' is deprecated, use 'std::uncaught_exceptions' instead | ||
// CHECK-FIXES: bool b{std::uncaught_exceptions() > 0}; | ||
|
||
MACRO(); | ||
// CHECK-MESSAGES: [[@LINE-1]]:3: warning: 'std::uncaught_exception' is deprecated, use 'std::uncaught_exceptions' instead | ||
// CHECK-FIXES: MACRO(); | ||
|
||
doSomething(std::uncaught_exception); | ||
// CHECK-MESSAGES: [[@LINE-1]]:15: warning: 'std::uncaught_exception' is deprecated, use 'std::uncaught_exceptions' instead | ||
// CHECK-FIXES: doSomething(std::uncaught_exception); | ||
|
||
doSomething(uncaught_exception); | ||
// CHECK-MESSAGES: [[@LINE-1]]:15: warning: 'std::uncaught_exception' is deprecated, use 'std::uncaught_exceptions' instead | ||
// CHECK-FIXES: doSomething(uncaught_exception); | ||
|
||
bool (*foo)(); | ||
foo = &uncaught_exception; | ||
// CHECK-MESSAGES: [[@LINE-1]]:10: warning: 'std::uncaught_exception' is deprecated, use 'std::uncaught_exceptions' instead | ||
// CHECK-FIXES: foo = &uncaught_exception; | ||
|
||
doSomething2<uncaught_exception>(); | ||
// CHECK-MESSAGES: [[@LINE-1]]:16: warning: 'std::uncaught_exception' is deprecated, use 'std::uncaught_exceptions' instead | ||
// CHECK-FIXES: doSomething2<uncaught_exception>(); | ||
} |