Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@
#include "TaggedUnionMemberCountCheck.h"
#include "TerminatingContinueCheck.h"
#include "ThrowKeywordMissingCheck.h"
#include "ThrowingStaticInitializationCheck.h"
#include "TooSmallLoopVariableCheck.h"
#include "UncheckedOptionalAccessCheck.h"
#include "UncheckedStringToNumberConversionCheck.h"
Expand Down Expand Up @@ -261,6 +262,8 @@ class BugproneModule : public ClangTidyModule {
"bugprone-terminating-continue");
CheckFactories.registerCheck<ThrowKeywordMissingCheck>(
"bugprone-throw-keyword-missing");
CheckFactories.registerCheck<ThrowingStaticInitializationCheck>(
"bugprone-throwing-static-initialization");
CheckFactories.registerCheck<TooSmallLoopVariableCheck>(
"bugprone-too-small-loop-variable");
CheckFactories.registerCheck<UncheckedOptionalAccessCheck>(
Expand Down
1 change: 1 addition & 0 deletions clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ add_clang_library(clangTidyBugproneModule STATIC
TaggedUnionMemberCountCheck.cpp
TerminatingContinueCheck.cpp
ThrowKeywordMissingCheck.cpp
ThrowingStaticInitializationCheck.cpp
TooSmallLoopVariableCheck.cpp
UncheckedOptionalAccessCheck.cpp
UncheckedStringToNumberConversionCheck.cpp
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@
//
//===----------------------------------------------------------------------===//

#include "StaticObjectExceptionCheck.h"
#include "ThrowingStaticInitializationCheck.h"
#include "clang/AST/ASTContext.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"

using namespace clang::ast_matchers;

namespace clang::tidy::cert {
namespace clang::tidy::bugprone {

void StaticObjectExceptionCheck::registerMatchers(MatchFinder *Finder) {
void ThrowingStaticInitializationCheck::registerMatchers(MatchFinder *Finder) {
// Match any static or thread_local variable declaration that has an
// initializer that can throw.
Finder->addMatcher(
Expand All @@ -34,7 +34,8 @@ void StaticObjectExceptionCheck::registerMatchers(MatchFinder *Finder) {
this);
}

void StaticObjectExceptionCheck::check(const MatchFinder::MatchResult &Result) {
void ThrowingStaticInitializationCheck::check(
const MatchFinder::MatchResult &Result) {
const auto *VD = Result.Nodes.getNodeAs<VarDecl>("var");
const auto *Func = Result.Nodes.getNodeAs<FunctionDecl>("func");

Expand All @@ -52,4 +53,4 @@ void StaticObjectExceptionCheck::check(const MatchFinder::MatchResult &Result) {
}
}

} // namespace clang::tidy::cert
} // namespace clang::tidy::bugprone
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,21 @@
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CERT_ERR58_CPP_H
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CERT_ERR58_CPP_H
#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_THROWINGSTATICINITIALIZATIONCHECK_H
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_THROWINGSTATICINITIALIZATIONCHECK_H

#include "../ClangTidyCheck.h"

namespace clang::tidy::cert {
namespace clang::tidy::bugprone {

/// Checks whether the constructor for a static or thread_local object will
/// throw.
///
/// For the user-facing documentation see:
/// http://clang.llvm.org/extra/clang-tidy/checks/cert/err58-cpp.html
class StaticObjectExceptionCheck : public ClangTidyCheck {
/// http://clang.llvm.org/extra/clang-tidy/checks/bugprone/throwing-static-initialization.html
class ThrowingStaticInitializationCheck : public ClangTidyCheck {
public:
StaticObjectExceptionCheck(StringRef Name, ClangTidyContext *Context)
ThrowingStaticInitializationCheck(StringRef Name, ClangTidyContext *Context)
: ClangTidyCheck(Name, Context) {}
bool isLanguageVersionSupported(const LangOptions &LangOpts) const override {
return getLangOpts().CPlusPlus && getLangOpts().CXXExceptions;
Expand All @@ -29,6 +29,6 @@ class StaticObjectExceptionCheck : public ClangTidyCheck {
void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
};

} // namespace clang::tidy::cert
} // namespace clang::tidy::bugprone

#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CERT_ERR58_CPP_H
#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_THROWINGSTATICINITIALIZATIONCHECK_H
5 changes: 3 additions & 2 deletions clang-tools-extra/clang-tidy/cert/CERTTidyModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "../bugprone/SizeofExpressionCheck.h"
#include "../bugprone/SpuriouslyWakeUpFunctionsCheck.h"
#include "../bugprone/SuspiciousMemoryComparisonCheck.h"
#include "../bugprone/ThrowingStaticInitializationCheck.h"
#include "../bugprone/UncheckedStringToNumberConversionCheck.h"
#include "../bugprone/UnhandledSelfAssignmentCheck.h"
#include "../bugprone/UnsafeFunctionsCheck.h"
Expand All @@ -39,7 +40,6 @@
#include "NonTrivialTypesLibcMemoryCallsCheck.h"
#include "ProperlySeededRandomGeneratorCheck.h"
#include "SetLongJmpCheck.h"
#include "StaticObjectExceptionCheck.h"
#include "ThrownExceptionTypeCheck.h"
#include "VariadicFunctionDefCheck.h"

Expand Down Expand Up @@ -257,7 +257,8 @@ class CERTModule : public ClangTidyModule {
CheckFactories.registerCheck<misc::ThrowByValueCatchByReferenceCheck>(
"cert-err09-cpp");
CheckFactories.registerCheck<SetLongJmpCheck>("cert-err52-cpp");
CheckFactories.registerCheck<StaticObjectExceptionCheck>("cert-err58-cpp");
CheckFactories.registerCheck<bugprone::ThrowingStaticInitializationCheck>(
"cert-err58-cpp");
CheckFactories.registerCheck<ThrownExceptionTypeCheck>("cert-err60-cpp");
CheckFactories.registerCheck<misc::ThrowByValueCatchByReferenceCheck>(
"cert-err61-cpp");
Expand Down
1 change: 0 additions & 1 deletion clang-tools-extra/clang-tidy/cert/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ add_clang_library(clangTidyCERTModule STATIC
NonTrivialTypesLibcMemoryCallsCheck.cpp
ProperlySeededRandomGeneratorCheck.cpp
SetLongJmpCheck.cpp
StaticObjectExceptionCheck.cpp
ThrownExceptionTypeCheck.cpp
VariadicFunctionDefCheck.cpp

Expand Down
5 changes: 5 additions & 0 deletions clang-tools-extra/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,11 @@ New check aliases
<clang-tidy/checks/bugprone/unchecked-string-to-number-conversion>`
keeping initial check as an alias to the new one.

- Renamed :doc:`cert-err58-cpp <clang-tidy/checks/cert/err58-cpp>` to
:doc:`bugprone-throwing-static-initialization
<clang-tidy/checks/bugprone/throwing-static-initialization>`
keeping initial check as an alias to the new one.

Changes in existing checks
^^^^^^^^^^^^^^^^^^^^^^^^^^

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
.. title:: clang-tidy - bugprone-throwing-static-initialization

bugprone-throwing-static-initialization
=======================================

Finds all ``static`` or ``thread_local`` variable declarations where the
initializer for the object may throw an exception.

References
----------

This check corresponds to the CERT C++ Coding Standard rule
`ERR58-CPP. Handle all exceptions thrown before main() begins executing
<https://www.securecoding.cert.org/confluence/display/cplusplus/ERR58-CPP.+Handle+all+exceptions+thrown+before+main%28%29+begins+executing>`_.
7 changes: 5 additions & 2 deletions clang-tools-extra/docs/clang-tidy/checks/cert/err58-cpp.rst
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
.. title:: clang-tidy - cert-err58-cpp
.. meta::
:http-equiv=refresh: 5;URL=../bugprone/throwing-static-initialization.html

cert-err58-cpp
==============

This check flags all ``static`` or ``thread_local`` variable declarations where
the initializer for the object may throw an exception.
The `cert-err58-cpp` check is an alias, please see
`bugprone-throwing-static-initialization <../bugprone/throwing-static-initialization.html>`_
for more information.

This check corresponds to the CERT C++ Coding Standard rule
`ERR58-CPP. Handle all exceptions thrown before main() begins executing
Expand Down
3 changes: 2 additions & 1 deletion clang-tools-extra/docs/clang-tidy/checks/list.rst
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ Clang-Tidy Checks
:doc:`bugprone-tagged-union-member-count <bugprone/tagged-union-member-count>`,
:doc:`bugprone-terminating-continue <bugprone/terminating-continue>`, "Yes"
:doc:`bugprone-throw-keyword-missing <bugprone/throw-keyword-missing>`,
:doc:`bugprone-throwing-static-initialization <bugprone/throwing-static-initialization>`,
:doc:`bugprone-too-small-loop-variable <bugprone/too-small-loop-variable>`,
:doc:`bugprone-unchecked-optional-access <bugprone/unchecked-optional-access>`,
:doc:`bugprone-unchecked-string-to-number-conversion <bugprone/unchecked-string-to-number-conversion>`,
Expand All @@ -176,7 +177,6 @@ Clang-Tidy Checks
:doc:`cert-env33-c <cert/env33-c>`,
:doc:`cert-err33-c <cert/err33-c>`,
:doc:`cert-err52-cpp <cert/err52-cpp>`,
:doc:`cert-err58-cpp <cert/err58-cpp>`,
:doc:`cert-err60-cpp <cert/err60-cpp>`,
:doc:`cert-flp30-c <cert/flp30-c>`,
:doc:`cert-mem57-cpp <cert/mem57-cpp>`,
Expand Down Expand Up @@ -440,6 +440,7 @@ Check aliases
:doc:`cert-dcl59-cpp <cert/dcl59-cpp>`, :doc:`google-build-namespaces <google/build-namespaces>`,
:doc:`cert-err09-cpp <cert/err09-cpp>`, :doc:`misc-throw-by-value-catch-by-reference <misc/throw-by-value-catch-by-reference>`,
:doc:`cert-err34-c <cert/err34-c>`, :doc:`bugprone-unchecked-string-to-number-conversion <bugprone/unchecked-string-to-number-conversion>`,
:doc:`cert-err58-cpp <cert/err58-cpp>`, :doc:`bugprone-throwing-static-initialization <bugprone/throwing-static-initialization>`,
:doc:`cert-err61-cpp <cert/err61-cpp>`, :doc:`misc-throw-by-value-catch-by-reference <misc/throw-by-value-catch-by-reference>`,
:doc:`cert-exp42-c <cert/exp42-c>`, :doc:`bugprone-suspicious-memory-comparison <bugprone/suspicious-memory-comparison>`,
:doc:`cert-fio38-c <cert/fio38-c>`, :doc:`misc-non-copyable-objects <misc/non-copyable-objects>`,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// RUN: clang-tidy %s -checks="-*,cert-err58-cpp" -- -std=c++17 -target x86_64-pc-linux-gnu \
// RUN: clang-tidy %s -checks="-*,bugprone-throwing-static-initialization" -- -std=c++17 -target x86_64-pc-linux-gnu \
// RUN: | FileCheck %s -check-prefix=CHECK-EXCEPTIONS \
// RUN: -implicit-check-not="{{warning|error}}:"
// RUN: clang-tidy %s -checks="-*,cert-err58-cpp" -- -DNONEXCEPTIONS -fno-exceptions -std=c++17 -target x86_64-pc-linux-gnu \
// RUN: clang-tidy %s -checks="-*,bugprone-throwing-static-initialization" -- -DNONEXCEPTIONS -fno-exceptions -std=c++17 -target x86_64-pc-linux-gnu \
// RUN: | FileCheck %s -allow-empty -check-prefix=CHECK-NONEXCEPTIONS \
// RUN: -implicit-check-not="{{warning|error}}:"

Expand Down Expand Up @@ -57,7 +57,7 @@ UserConv_Bad some_bad_func() noexcept;
UserConv_Good some_good_func() noexcept;

S s;
// CHECK-EXCEPTIONS: :[[@LINE-1]]:3: warning: initialization of 's' with static storage duration may throw an exception that cannot be caught [cert-err58-cpp]
// CHECK-EXCEPTIONS: :[[@LINE-1]]:3: warning: initialization of 's' with static storage duration may throw an exception that cannot be caught [bugprone-throwing-static-initialization]
// CHECK-EXCEPTIONS: 9:3: note: possibly throwing constructor declared here
// CHECK-NONEXCEPTIONS-NOT: warning:
T t; // ok
Expand Down Expand Up @@ -146,7 +146,7 @@ void f(S s1, T t1, U u1, V v1, W w1) { // ok, ok, ok, ok, ok

namespace {
S s;
// CHECK-EXCEPTIONS: :[[@LINE-1]]:3: warning: initialization of 's' with static storage duration may throw an exception that cannot be caught [cert-err58-cpp]
// CHECK-EXCEPTIONS: :[[@LINE-1]]:3: warning: initialization of 's' with static storage duration may throw an exception that cannot be caught [bugprone-throwing-static-initialization]
// CHECK-EXCEPTIONS: 9:3: note: possibly throwing constructor declared here
// CHECK-NONEXCEPTIONS-NOT: warning:
T t; // ok
Expand Down Expand Up @@ -207,7 +207,7 @@ class Statics {
};

S Statics::s;
// CHECK-EXCEPTIONS: :[[@LINE-1]]:12: warning: initialization of 's' with static storage duration may throw an exception that cannot be caught [cert-err58-cpp]
// CHECK-EXCEPTIONS: :[[@LINE-1]]:12: warning: initialization of 's' with static storage duration may throw an exception that cannot be caught [bugprone-throwing-static-initialization]
// CHECK-EXCEPTIONS: 9:3: note: possibly throwing constructor declared here
// CHECK-NONEXCEPTIONS-NOT: warning:
T Statics::t;
Expand All @@ -231,7 +231,7 @@ constexpr int foo(int x) { if (x <= 0) throw 12; return x; }
constexpr int bar = foo(1); // OK
// CHECK-EXCEPTIONS-NOT: warning: initialization of 'bar' with static storage
int baz = foo(0); // Not OK; throws at runtime when exceptions are enabled.
// CHECK-EXCEPTIONS: :[[@LINE-1]]:5: warning: initialization of 'baz' with static storage duration may throw an exception that cannot be caught [cert-err58-cpp]
// CHECK-EXCEPTIONS: :[[@LINE-1]]:5: warning: initialization of 'baz' with static storage duration may throw an exception that cannot be caught [bugprone-throwing-static-initialization]
// CHECK-EXCEPTIONS: :[[@LINE-6]]:15: note: possibly throwing function declared here
} // namespace pr35457
#endif // NONEXCEPTIONS
Expand All @@ -243,10 +243,10 @@ struct T { T() noexcept; };
auto Okay1 = []{ S s; };
auto Okay2 = []{ (void)new int; };
auto NotOkay1 = []{ S s; return 12; }(); // Because the lambda call is not noexcept
// CHECK-EXCEPTIONS: :[[@LINE-1]]:6: warning: initialization of 'NotOkay1' with static storage duration may throw an exception that cannot be caught [cert-err58-cpp]
// CHECK-EXCEPTIONS: :[[@LINE-1]]:6: warning: initialization of 'NotOkay1' with static storage duration may throw an exception that cannot be caught [bugprone-throwing-static-initialization]
// CHECK-EXCEPTIONS: :[[@LINE-7]]:12: note: possibly throwing constructor declared here
auto NotOkay2 = []() noexcept { S s; return 12; }(); // Because S::S() is not noexcept
// CHECK-EXCEPTIONS: :[[@LINE-1]]:6: warning: initialization of 'NotOkay2' with static storage duration may throw an exception that cannot be caught [cert-err58-cpp]
// CHECK-EXCEPTIONS: :[[@LINE-1]]:6: warning: initialization of 'NotOkay2' with static storage duration may throw an exception that cannot be caught [bugprone-throwing-static-initialization]
// CHECK-EXCEPTIONS: :[[@LINE-10]]:12: note: possibly throwing constructor declared here
auto Okay3 = []() noexcept { T t; return t; }();

Expand All @@ -258,7 +258,7 @@ struct U {
};
auto Okay4 = []{ U u; return u.getBadLambda(); }();
auto NotOkay3 = []() noexcept { U u; return u.getBadLambda(); }()(); // Because the lambda returned and called is not noexcept
// CHECK-EXCEPTIONS: :[[@LINE-1]]:6: warning: initialization of 'NotOkay3' with static storage duration may throw an exception that cannot be caught [cert-err58-cpp]
// CHECK-EXCEPTIONS: :[[@LINE-1]]:6: warning: initialization of 'NotOkay3' with static storage duration may throw an exception that cannot be caught [bugprone-throwing-static-initialization]
// CHECK-EXCEPTIONS: :[[@LINE-6]]:12: note: possibly throwing function declared here

#ifndef NONEXCEPTIONS
Expand Down
Loading