forked from OSchip/llvm-project
[clang-tidy] Replace the usage of std::uncaught_exception with std::uncaught_exceptions
Patch by: Daniel Kolozsvari! Differential Revision: https://reviews.llvm.org/D40787 llvm-svn: 325572
This commit is contained in:
parent
b8f369d636
commit
76e5023dd3
|
@ -27,6 +27,7 @@ add_clang_library(clangTidyModernizeModule
|
|||
UseNullptrCheck.cpp
|
||||
UseOverrideCheck.cpp
|
||||
UseTransparentFunctorsCheck.cpp
|
||||
UseUncaughtExceptionsCheck.cpp
|
||||
UseUsingCheck.cpp
|
||||
|
||||
LINK_LIBS
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include "UseNullptrCheck.h"
|
||||
#include "UseOverrideCheck.h"
|
||||
#include "UseTransparentFunctorsCheck.h"
|
||||
#include "UseUncaughtExceptionsCheck.h"
|
||||
#include "UseUsingCheck.h"
|
||||
|
||||
using namespace clang::ast_matchers;
|
||||
|
@ -78,6 +79,8 @@ public:
|
|||
CheckFactories.registerCheck<UseOverrideCheck>("modernize-use-override");
|
||||
CheckFactories.registerCheck<UseTransparentFunctorsCheck>(
|
||||
"modernize-use-transparent-functors");
|
||||
CheckFactories.registerCheck<UseUncaughtExceptionsCheck>(
|
||||
"modernize-use-uncaught-exceptions");
|
||||
CheckFactories.registerCheck<UseUsingCheck>("modernize-use-using");
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -105,6 +105,11 @@ Improvements to clang-tidy
|
|||
|
||||
Diagnoses when a temporary object that appears to be an exception is constructed but not thrown.
|
||||
|
||||
- New `modernize-use-uncaught-exceptions
|
||||
<http://clang.llvm.org/extra/clang-tidy/checks/modernize-use-uncaught-exceptions.html>`_ check
|
||||
|
||||
Finds and replaces deprecated uses of std::uncaught_exception to std::uncaught_exceptions()
|
||||
|
||||
Improvements to include-fixer
|
||||
-----------------------------
|
||||
|
||||
|
|
|
@ -177,6 +177,7 @@ Clang-Tidy Checks
|
|||
modernize-use-nullptr
|
||||
modernize-use-override
|
||||
modernize-use-transparent-functors
|
||||
modernize-use-uncaught-exceptions
|
||||
modernize-use-using
|
||||
mpi-buffer-deref
|
||||
mpi-type-mismatch
|
||||
|
|
|
@ -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();
|
||||
}
|
|
@ -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>();
|
||||
}
|
Loading…
Reference in New Issue