forked from OSchip/llvm-project
Implement a new clang-tidy check that suggests users replace dynamic exception specifications with noexcept exception specifications.
Patch by Don Hinton. llvm-svn: 293217
This commit is contained in:
parent
1ea5f324bd
commit
8ec373af3d
|
@ -20,6 +20,7 @@ add_clang_library(clangTidyModernizeModule
|
|||
UseEmplaceCheck.cpp
|
||||
UseEqualsDefaultCheck.cpp
|
||||
UseEqualsDeleteCheck.cpp
|
||||
UseNoexceptCheck.cpp
|
||||
UseNullptrCheck.cpp
|
||||
UseOverrideCheck.cpp
|
||||
UseTransparentFunctorsCheck.cpp
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include "UseEmplaceCheck.h"
|
||||
#include "UseEqualsDefaultCheck.h"
|
||||
#include "UseEqualsDeleteCheck.h"
|
||||
#include "UseNoexceptCheck.h"
|
||||
#include "UseNullptrCheck.h"
|
||||
#include "UseOverrideCheck.h"
|
||||
#include "UseTransparentFunctorsCheck.h"
|
||||
|
@ -63,6 +64,7 @@ public:
|
|||
CheckFactories.registerCheck<UseEqualsDefaultCheck>("modernize-use-equals-default");
|
||||
CheckFactories.registerCheck<UseEqualsDeleteCheck>(
|
||||
"modernize-use-equals-delete");
|
||||
CheckFactories.registerCheck<UseNoexceptCheck>("modernize-use-noexcept");
|
||||
CheckFactories.registerCheck<UseNullptrCheck>("modernize-use-nullptr");
|
||||
CheckFactories.registerCheck<UseOverrideCheck>("modernize-use-override");
|
||||
CheckFactories.registerCheck<UseTransparentFunctorsCheck>(
|
||||
|
|
|
@ -0,0 +1,114 @@
|
|||
//===--- UseNoexceptCheck.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 "UseNoexceptCheck.h"
|
||||
#include "clang/AST/ASTContext.h"
|
||||
#include "clang/Lex/Lexer.h"
|
||||
|
||||
using namespace clang::ast_matchers;
|
||||
|
||||
namespace clang {
|
||||
namespace tidy {
|
||||
namespace modernize {
|
||||
|
||||
UseNoexceptCheck::UseNoexceptCheck(StringRef Name, ClangTidyContext *Context)
|
||||
: ClangTidyCheck(Name, Context),
|
||||
NoexceptMacro(Options.get("ReplacementString", "")),
|
||||
UseNoexceptFalse(Options.get("UseNoexceptFalse", true)) {}
|
||||
|
||||
void UseNoexceptCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
|
||||
Options.store(Opts, "ReplacementString", NoexceptMacro);
|
||||
Options.store(Opts, "UseNoexceptFalse", UseNoexceptFalse);
|
||||
}
|
||||
|
||||
void UseNoexceptCheck::registerMatchers(MatchFinder *Finder) {
|
||||
if (!getLangOpts().CPlusPlus11)
|
||||
return;
|
||||
|
||||
Finder->addMatcher(
|
||||
functionDecl(
|
||||
cxxMethodDecl(
|
||||
hasTypeLoc(loc(functionProtoType(hasDynamicExceptionSpec()))),
|
||||
anyOf(hasOverloadedOperatorName("delete[]"),
|
||||
hasOverloadedOperatorName("delete"), cxxDestructorDecl()))
|
||||
.bind("del-dtor"))
|
||||
.bind("funcDecl"),
|
||||
this);
|
||||
|
||||
Finder->addMatcher(
|
||||
functionDecl(
|
||||
hasTypeLoc(loc(functionProtoType(hasDynamicExceptionSpec()))),
|
||||
unless(anyOf(hasOverloadedOperatorName("delete[]"),
|
||||
hasOverloadedOperatorName("delete"),
|
||||
cxxDestructorDecl())))
|
||||
.bind("funcDecl"),
|
||||
this);
|
||||
|
||||
Finder->addMatcher(
|
||||
parmVarDecl(anyOf(hasType(pointerType(pointee(parenType(innerType(
|
||||
functionProtoType(hasDynamicExceptionSpec())))))),
|
||||
hasType(memberPointerType(pointee(parenType(innerType(
|
||||
functionProtoType(hasDynamicExceptionSpec()))))))))
|
||||
.bind("parmVarDecl"),
|
||||
this);
|
||||
}
|
||||
|
||||
void UseNoexceptCheck::check(const MatchFinder::MatchResult &Result) {
|
||||
const FunctionProtoType *FnTy = nullptr;
|
||||
bool DtorOrOperatorDel = false;
|
||||
SourceRange Range;
|
||||
|
||||
if (const auto *FuncDecl = Result.Nodes.getNodeAs<FunctionDecl>("funcDecl")) {
|
||||
DtorOrOperatorDel = Result.Nodes.getNodeAs<FunctionDecl>("del-dtor");
|
||||
FnTy = FuncDecl->getType()->getAs<FunctionProtoType>();
|
||||
if (const auto *TSI = FuncDecl->getTypeSourceInfo())
|
||||
Range =
|
||||
TSI->getTypeLoc().castAs<FunctionTypeLoc>().getExceptionSpecRange();
|
||||
} else if (const auto *ParmDecl =
|
||||
Result.Nodes.getNodeAs<ParmVarDecl>("parmVarDecl")) {
|
||||
FnTy = ParmDecl->getType()
|
||||
->getAs<Type>()
|
||||
->getPointeeType()
|
||||
->getAs<FunctionProtoType>();
|
||||
|
||||
if (const auto *TSI = ParmDecl->getTypeSourceInfo())
|
||||
Range = TSI->getTypeLoc()
|
||||
.getNextTypeLoc()
|
||||
.IgnoreParens()
|
||||
.castAs<FunctionProtoTypeLoc>()
|
||||
.getExceptionSpecRange();
|
||||
}
|
||||
CharSourceRange CRange = Lexer::makeFileCharRange(
|
||||
CharSourceRange::getTokenRange(Range), *Result.SourceManager,
|
||||
Result.Context->getLangOpts());
|
||||
|
||||
assert(FnTy && "FunctionProtoType is null.");
|
||||
bool IsNoThrow = FnTy->isNothrow(*Result.Context);
|
||||
StringRef ReplacementStr =
|
||||
IsNoThrow
|
||||
? NoexceptMacro.empty() ? "noexcept" : NoexceptMacro
|
||||
: NoexceptMacro.empty()
|
||||
? (DtorOrOperatorDel || UseNoexceptFalse) ? "noexcept(false)"
|
||||
: ""
|
||||
: "";
|
||||
|
||||
FixItHint FixIt;
|
||||
if ((IsNoThrow || NoexceptMacro.empty()) && CRange.isValid())
|
||||
FixIt = FixItHint::CreateReplacement(CRange, ReplacementStr);
|
||||
|
||||
diag(Range.getBegin(), "dynamic exception specification '%0' is deprecated; "
|
||||
"consider %select{using '%2'|removing it}1 instead")
|
||||
<< Lexer::getSourceText(CRange, *Result.SourceManager,
|
||||
Result.Context->getLangOpts())
|
||||
<< ReplacementStr.empty() << ReplacementStr << FixIt;
|
||||
}
|
||||
|
||||
} // namespace modernize
|
||||
} // namespace tidy
|
||||
} // namespace clang
|
|
@ -0,0 +1,49 @@
|
|||
//===--- UseNoexceptCheck.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_NOEXCEPT_H
|
||||
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_USE_NOEXCEPT_H
|
||||
|
||||
#include "../ClangTidy.h"
|
||||
|
||||
namespace clang {
|
||||
namespace tidy {
|
||||
namespace modernize {
|
||||
|
||||
/// \brief Replace dynamic exception specifications, with
|
||||
/// `noexcept` (or user-defined macro) or `noexcept(false)`.
|
||||
/// \code
|
||||
/// void foo() throw();
|
||||
/// void bar() throw(int);
|
||||
/// \endcode
|
||||
/// Is converted to:
|
||||
/// \code
|
||||
/// void foo() ;
|
||||
// void bar() noexcept(false);
|
||||
/// \endcode
|
||||
///
|
||||
/// For the user-facing documentation see:
|
||||
/// http://clang.llvm.org/extra/clang-tidy/checks/modernize-use-noexcept.html
|
||||
class UseNoexceptCheck : public ClangTidyCheck {
|
||||
public:
|
||||
UseNoexceptCheck(StringRef Name, ClangTidyContext *Context);
|
||||
void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
|
||||
void registerMatchers(ast_matchers::MatchFinder *Finder) override;
|
||||
void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
|
||||
|
||||
private:
|
||||
const std::string NoexceptMacro;
|
||||
bool UseNoexceptFalse;
|
||||
};
|
||||
|
||||
} // namespace modernize
|
||||
} // namespace tidy
|
||||
} // namespace clang
|
||||
|
||||
#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_USE_NOEXCEPT_H
|
|
@ -57,7 +57,10 @@ The improvements are...
|
|||
Improvements to clang-tidy
|
||||
--------------------------
|
||||
|
||||
The improvements are...
|
||||
- New `modernize-use-noexcept
|
||||
<http://clang.llvm.org/extra/clang-tidy/checks/modernize-use-noexcept.html>`_ check
|
||||
|
||||
Replaces dynamic exception specifications with ``noexcept`` or a user defined macro.
|
||||
|
||||
Improvements to include-fixer
|
||||
-----------------------------
|
||||
|
|
|
@ -116,6 +116,7 @@ Clang-Tidy Checks
|
|||
modernize-use-emplace
|
||||
modernize-use-equals-default
|
||||
modernize-use-equals-delete
|
||||
modernize-use-noexcept
|
||||
modernize-use-nullptr
|
||||
modernize-use-override
|
||||
modernize-use-transparent-functors
|
||||
|
|
|
@ -0,0 +1,90 @@
|
|||
.. title:: clang-tidy - modernize-use-noexcept
|
||||
|
||||
modernize-use-noexcept
|
||||
======================
|
||||
|
||||
This check replaces deprecated dynamic exception specifications with
|
||||
the appropriate noexcept specification (introduced in C++11). By
|
||||
default this check will replace ``throw()`` with ``noexcept``,
|
||||
and ``throw(<exception>[,...])`` or ``throw(...)`` with
|
||||
``noexcept(false)``.
|
||||
|
||||
Example
|
||||
-------
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
void foo() throw();
|
||||
void bar() throw(int) {}
|
||||
|
||||
transforms to:
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
void foo() noexcept;
|
||||
void bar() noexcept(false) {}
|
||||
|
||||
Options
|
||||
-------
|
||||
|
||||
.. option:: ReplacementString
|
||||
|
||||
Users can use :option:`ReplacementString` to specify a macro to use
|
||||
instead of ``noexcept``. This is useful when maintaining source code
|
||||
that uses custom exception specification marking other than
|
||||
``noexcept``. Fixit hints will only be generated for non-throwing
|
||||
specifications.
|
||||
|
||||
Example
|
||||
^^^^^^^
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
void bar() throw(int);
|
||||
void foo() throw();
|
||||
|
||||
transforms to:
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
void bar() throw(int); // No Fixit generated.
|
||||
void foo() NOEXCEPT;
|
||||
|
||||
if the :option:`ReplacementString` option is set to `NOEXCEPT`.
|
||||
|
||||
.. option:: UseNoexceptFalse
|
||||
|
||||
Enabled by default, disabling will generate Fixit hints that remove
|
||||
throwing dynamic exception specs, e.g., ``throw(<something>)``,
|
||||
completely without providing a replacement text, except for
|
||||
destructors and delete operators that are ``noexcept(true)`` by
|
||||
default.
|
||||
|
||||
Example
|
||||
^^^^^^^
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
void foo() throw(int) {}
|
||||
|
||||
struct bar {
|
||||
void foobar() throw(int);
|
||||
void operator delete(void *ptr) throw(int);
|
||||
void operator delete[](void *ptr) throw(int);
|
||||
~bar() throw(int);
|
||||
}
|
||||
|
||||
transforms to:
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
void foo() {}
|
||||
|
||||
struct bar {
|
||||
void foobar();
|
||||
void operator delete(void *ptr) noexcept(false);
|
||||
void operator delete[](void *ptr) noexcept(false);
|
||||
~bar() noexcept(false);
|
||||
}
|
||||
|
||||
if the :option:`UseNoexceptFalse` option is set to `0`.
|
|
@ -0,0 +1,36 @@
|
|||
// RUN: %check_clang_tidy %s modernize-use-noexcept %t -- \
|
||||
// RUN: -config="{CheckOptions: [{key: modernize-use-noexcept.ReplacementString, value: 'NOEXCEPT'}]}" \
|
||||
// RUN: -- -std=c++11
|
||||
|
||||
// Example definition of NOEXCEPT -- simplified test to see if noexcept is supported.
|
||||
#if (__has_feature(cxx_noexcept))
|
||||
#define NOEXCEPT noexcept
|
||||
#else
|
||||
#define NOEXCEPT throw()
|
||||
#endif
|
||||
|
||||
void bar() throw() {}
|
||||
// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: dynamic exception specification 'throw()' is deprecated; consider using 'NOEXCEPT' instead [modernize-use-noexcept]
|
||||
// CHECK-FIXES: void bar() NOEXCEPT {}
|
||||
|
||||
// Should not trigger a FixItHint, since macros only support noexcept, and this
|
||||
// case throws.
|
||||
class A {};
|
||||
class B {};
|
||||
void foobar() throw(A, B);
|
||||
// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: dynamic exception specification 'throw(A, B)' is deprecated; consider removing it instead [modernize-use-noexcept]
|
||||
|
||||
// Should not trigger a replacement.
|
||||
void foo() noexcept(true);
|
||||
|
||||
struct Z {
|
||||
void operator delete(void *ptr) throw();
|
||||
void operator delete[](void *ptr) throw(int);
|
||||
~Z() throw(int) {}
|
||||
};
|
||||
// CHECK-MESSAGES: :[[@LINE-4]]:35: warning: dynamic exception specification 'throw()' is deprecated; consider using 'NOEXCEPT' instead [modernize-use-noexcept]
|
||||
// CHECK-MESSAGES: :[[@LINE-4]]:37: warning: dynamic exception specification 'throw(int)' is deprecated; consider removing it instead [modernize-use-noexcept]
|
||||
// CHECK-MESSAGES: :[[@LINE-4]]:8: warning: dynamic exception specification 'throw(int)' is deprecated; consider removing it instead [modernize-use-noexcept]
|
||||
// CHECK-FIXES: void operator delete(void *ptr) NOEXCEPT;
|
||||
// CHECK-FIXES: void operator delete[](void *ptr) throw(int);
|
||||
// CHECK-FIXES: ~Z() throw(int) {}
|
|
@ -0,0 +1,88 @@
|
|||
// RUN: %check_clang_tidy %s modernize-use-noexcept %t -- \
|
||||
// RUN: -config="{CheckOptions: [{key: modernize-use-noexcept.UseNoexceptFalse, value: 0}]}" \
|
||||
// RUN: -- -std=c++11
|
||||
|
||||
class A {};
|
||||
class B {};
|
||||
|
||||
void foo() throw();
|
||||
// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: dynamic exception specification 'throw()' is deprecated; consider using 'noexcept' instead [modernize-use-noexcept]
|
||||
// CHECK-FIXES: void foo() noexcept;
|
||||
|
||||
void bar() throw(...);
|
||||
// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: dynamic exception specification 'throw(...)' is deprecated; consider removing it instead [modernize-use-noexcept]
|
||||
// CHECK-FIXES: void bar() ;
|
||||
|
||||
void k() throw(int(int));
|
||||
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: dynamic exception specification 'throw(int(int))' is deprecated; consider removing it instead [modernize-use-noexcept]
|
||||
// CHECK-FIXES: void k() ;
|
||||
|
||||
void foobar() throw(A, B)
|
||||
{}
|
||||
// CHECK-MESSAGES: :[[@LINE-2]]:15: warning: dynamic exception specification 'throw(A, B)' is deprecated; consider removing it instead [modernize-use-noexcept]
|
||||
// CHECK-FIXES: void foobar()
|
||||
|
||||
void baz(int = (throw A(), 0)) throw(A, B) {}
|
||||
// CHECK-MESSAGES: :[[@LINE-1]]:32: warning: dynamic exception specification 'throw(A, B)' is deprecated; consider removing it instead [modernize-use-noexcept]
|
||||
// CHECK-FIXES: void baz(int = (throw A(), 0)) {}
|
||||
|
||||
void g(void (*fp)(void) throw());
|
||||
// CHECK-MESSAGES: :[[@LINE-1]]:25: warning: dynamic exception specification 'throw()' is deprecated; consider using 'noexcept' instead [modernize-use-noexcept]
|
||||
// CHECK-FIXES: void g(void (*fp)(void) noexcept);
|
||||
|
||||
void f(void (*fp)(void) throw(int)) throw(char);
|
||||
// CHECK-MESSAGES: :[[@LINE-1]]:25: warning: dynamic exception specification 'throw(int)' is deprecated; consider removing it instead [modernize-use-noexcept]
|
||||
// CHECK-MESSAGES: :[[@LINE-2]]:37: warning: dynamic exception specification 'throw(char)' is deprecated; consider removing it instead [modernize-use-noexcept]
|
||||
// CHECK-FIXES: void f(void (*fp)(void) ) ;
|
||||
|
||||
#define THROW throw
|
||||
void h(void (*fp)(void) THROW(int)) THROW(char);
|
||||
// CHECK-MESSAGES: :[[@LINE-1]]:25: warning: dynamic exception specification 'THROW(int)' is deprecated; consider removing it instead [modernize-use-noexcept]
|
||||
// CHECK-MESSAGES: :[[@LINE-2]]:37: warning: dynamic exception specification 'THROW(char)' is deprecated; consider removing it instead [modernize-use-noexcept]
|
||||
// CHECK-FIXES: void h(void (*fp)(void) ) ;
|
||||
|
||||
void j() throw(int(int) throw(void(void) throw(int)));
|
||||
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: dynamic exception specification 'throw(int(int) throw(void(void) throw(int)))' is deprecated; consider removing it instead [modernize-use-noexcept]
|
||||
// CHECK-FIXES: void j() ;
|
||||
|
||||
class Y {
|
||||
Y() throw() = default;
|
||||
};
|
||||
// CHECK-MESSAGES: :[[@LINE-2]]:7: warning: dynamic exception specification 'throw()' is deprecated; consider using 'noexcept' instead [modernize-use-noexcept]
|
||||
// CHECK-FIXES: Y() noexcept = default;
|
||||
|
||||
struct Z {
|
||||
void operator delete(void *ptr) throw();
|
||||
void operator delete[](void *ptr) throw(int);
|
||||
~Z() throw(int) {}
|
||||
};
|
||||
// CHECK-MESSAGES: :[[@LINE-4]]:35: warning: dynamic exception specification 'throw()' is deprecated; consider using 'noexcept' instead [modernize-use-noexcept]
|
||||
// CHECK-MESSAGES: :[[@LINE-4]]:37: warning: dynamic exception specification 'throw(int)' is deprecated; consider using 'noexcept(false)' instead [modernize-use-noexcept]
|
||||
// CHECK-MESSAGES: :[[@LINE-4]]:8: warning: dynamic exception specification 'throw(int)' is deprecated; consider using 'noexcept(false)' instead [modernize-use-noexcept]
|
||||
// CHECK-FIXES: void operator delete(void *ptr) noexcept;
|
||||
// CHECK-FIXES: void operator delete[](void *ptr) noexcept(false);
|
||||
// CHECK-FIXES: ~Z() noexcept(false) {}
|
||||
|
||||
struct S {
|
||||
void f() throw();
|
||||
};
|
||||
void f(void (S::*)() throw());
|
||||
// CHECK-MESSAGES: :[[@LINE-3]]:12: warning: dynamic exception specification 'throw()' is deprecated; consider using 'noexcept' instead [modernize-use-noexcept]
|
||||
// CHECK-MESSAGES: :[[@LINE-2]]:22: warning: dynamic exception specification 'throw()' is deprecated; consider using 'noexcept' instead [modernize-use-noexcept]
|
||||
// CHECK-FIXES: void f() noexcept;
|
||||
// CHECK-FIXES: void f(void (S::*)() noexcept);
|
||||
|
||||
typedef void (*fp)(void (*fp2)(int) throw());
|
||||
// CHECK-MESSAGES: :[[@LINE-1]]:37: warning: dynamic exception specification 'throw()' is deprecated; consider using 'noexcept' instead [modernize-use-noexcept]
|
||||
// CHECK-FIXES: typedef void (*fp)(void (*fp2)(int) noexcept);
|
||||
|
||||
// Should not trigger a replacement.
|
||||
void titi() noexcept {}
|
||||
void toto() noexcept(true) {}
|
||||
|
||||
// Should not trigger a replacement.
|
||||
void bad()
|
||||
#if !__has_feature(cxx_noexcept)
|
||||
throw()
|
||||
#endif
|
||||
;
|
|
@ -0,0 +1,104 @@
|
|||
// RUN: %check_clang_tidy %s modernize-use-noexcept %t -- \
|
||||
// RUN: -- -std=c++11
|
||||
|
||||
class A {};
|
||||
class B {};
|
||||
|
||||
void foo() throw();
|
||||
// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: dynamic exception specification 'throw()' is deprecated; consider using 'noexcept' instead [modernize-use-noexcept]
|
||||
// CHECK-FIXES: void foo() noexcept;
|
||||
|
||||
template <typename T>
|
||||
void foo() throw();
|
||||
void footest() { foo<int>(); foo<double>(); }
|
||||
// CHECK-MESSAGES: :[[@LINE-2]:12: warning: dynamic exception specification 'throw()' is deprecated; consider using 'noexcept' instead [modernize-use-noexcept]
|
||||
// CHECK-FIXES: void foo() noexcept;
|
||||
|
||||
void bar() throw(...);
|
||||
// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: dynamic exception specification 'throw(...)' is deprecated; consider using 'noexcept(false)' instead [modernize-use-noexcept]
|
||||
// CHECK-FIXES: void bar() noexcept(false);
|
||||
|
||||
void k() throw(int(int));
|
||||
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: dynamic exception specification 'throw(int(int))' is deprecated; consider using 'noexcept(false)' instead [modernize-use-noexcept]
|
||||
// CHECK-FIXES: void k() noexcept(false);
|
||||
|
||||
void foobar() throw(A, B)
|
||||
{}
|
||||
// CHECK-MESSAGES: :[[@LINE-2]]:15: warning: dynamic exception specification 'throw(A, B)' is deprecated; consider using 'noexcept(false)' instead [modernize-use-noexcept]
|
||||
// CHECK-FIXES: void foobar() noexcept(false)
|
||||
|
||||
void baz(int = (throw A(), 0)) throw(A, B) {}
|
||||
// CHECK-MESSAGES: :[[@LINE-1]]:32: warning: dynamic exception specification 'throw(A, B)' is deprecated; consider using 'noexcept(false)' instead [modernize-use-noexcept]
|
||||
// CHECK-FIXES: void baz(int = (throw A(), 0)) noexcept(false) {}
|
||||
|
||||
void g(void (*fp)(void) throw());
|
||||
// CHECK-MESSAGES: :[[@LINE-1]]:25: warning: dynamic exception specification 'throw()' is deprecated; consider using 'noexcept' instead [modernize-use-noexcept]
|
||||
// CHECK-FIXES: void g(void (*fp)(void) noexcept);
|
||||
|
||||
void f(void (*fp)(void) throw(int)) throw(char);
|
||||
// CHECK-MESSAGES: :[[@LINE-1]]:25: warning: dynamic exception specification 'throw(int)' is deprecated; consider using 'noexcept(false)' instead [modernize-use-noexcept]
|
||||
// CHECK-MESSAGES: :[[@LINE-2]]:37: warning: dynamic exception specification 'throw(char)' is deprecated; consider using 'noexcept(false)' instead [modernize-use-noexcept]
|
||||
// CHECK-FIXES: void f(void (*fp)(void) noexcept(false)) noexcept(false);
|
||||
|
||||
#define THROW throw
|
||||
void h(void (*fp)(void) THROW(int)) THROW(char);
|
||||
// CHECK-MESSAGES: :[[@LINE-1]]:25: warning: dynamic exception specification 'THROW(int)' is deprecated; consider using 'noexcept(false)' instead [modernize-use-noexcept]
|
||||
// CHECK-MESSAGES: :[[@LINE-2]]:37: warning: dynamic exception specification 'THROW(char)' is deprecated; consider using 'noexcept(false)' instead [modernize-use-noexcept]
|
||||
// CHECK-FIXES: void h(void (*fp)(void) noexcept(false)) noexcept(false);
|
||||
|
||||
void j() throw(int(int) throw(void(void) throw(int)));
|
||||
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: dynamic exception specification 'throw(int(int) throw(void(void) throw(int)))' is deprecated; consider using 'noexcept(false)' instead [modernize-use-noexcept]
|
||||
// CHECK-FIXES: void j() noexcept(false);
|
||||
|
||||
class Y {
|
||||
Y() throw() = default;
|
||||
};
|
||||
// CHECK-MESSAGES: :[[@LINE-2]]:7: warning: dynamic exception specification 'throw()' is deprecated; consider using 'noexcept' instead [modernize-use-noexcept]
|
||||
// CHECK-FIXES: Y() noexcept = default;
|
||||
|
||||
struct Z {
|
||||
void operator delete(void *ptr) throw();
|
||||
void operator delete[](void *ptr) throw(int);
|
||||
~Z() throw(int) {}
|
||||
};
|
||||
// CHECK-MESSAGES: :[[@LINE-4]]:35: warning: dynamic exception specification 'throw()' is deprecated; consider using 'noexcept' instead [modernize-use-noexcept]
|
||||
// CHECK-MESSAGES: :[[@LINE-4]]:37: warning: dynamic exception specification 'throw(int)' is deprecated; consider using 'noexcept(false)' instead [modernize-use-noexcept]
|
||||
// CHECK-MESSAGES: :[[@LINE-4]]:8: warning: dynamic exception specification 'throw(int)' is deprecated; consider using 'noexcept(false)' instead [modernize-use-noexcept]
|
||||
// CHECK-FIXES: void operator delete(void *ptr) noexcept;
|
||||
// CHECK-FIXES: void operator delete[](void *ptr) noexcept(false);
|
||||
// CHECK-FIXES: ~Z() noexcept(false) {}
|
||||
|
||||
struct S {
|
||||
void f() throw();
|
||||
};
|
||||
void f(void (S::*)() throw());
|
||||
// CHECK-MESSAGES: :[[@LINE-3]]:12: warning: dynamic exception specification 'throw()' is deprecated; consider using 'noexcept' instead [modernize-use-noexcept]
|
||||
// CHECK-MESSAGES: :[[@LINE-2]]:22: warning: dynamic exception specification 'throw()' is deprecated; consider using 'noexcept' instead [modernize-use-noexcept]
|
||||
// CHECK-FIXES: void f() noexcept;
|
||||
// CHECK-FIXES: void f(void (S::*)() noexcept);
|
||||
|
||||
template <typename T>
|
||||
struct ST {
|
||||
void foo() throw();
|
||||
};
|
||||
template <typename T>
|
||||
void ft(void (ST<T>::*)() throw());
|
||||
// CHECK-MESSAGES: :[[@LINE-4]]:14: warning: dynamic exception specification 'throw()' is deprecated; consider using 'noexcept' instead [modernize-use-noexcept]
|
||||
// CHECK-MESSAGES: :[[@LINE-2]]:27: warning: dynamic exception specification 'throw()' is deprecated; consider using 'noexcept' instead [modernize-use-noexcept]
|
||||
// CHECK-FIXES: void foo() noexcept;
|
||||
// CHECK-FIXES: void ft(void (ST<T>::*)() noexcept);
|
||||
|
||||
typedef void (*fp)(void (*fp2)(int) throw());
|
||||
// CHECK-MESSAGES: :[[@LINE-1]]:37: warning: dynamic exception specification 'throw()' is deprecated; consider using 'noexcept' instead [modernize-use-noexcept]
|
||||
// CHECK-FIXES: typedef void (*fp)(void (*fp2)(int) noexcept);
|
||||
|
||||
// Should not trigger a replacement.
|
||||
void titi() noexcept {}
|
||||
void toto() noexcept(true) {}
|
||||
|
||||
// Should not trigger a replacement.
|
||||
void bad()
|
||||
#if !__has_feature(cxx_noexcept)
|
||||
throw()
|
||||
#endif
|
||||
;
|
Loading…
Reference in New Issue