Skip to content
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
//
//===----------------------------------------------------------------------===//

#include "SetLongJmpCheck.h"
#include "AvoidSetjmpLongjmpCheck.h"
#include "clang/AST/ASTContext.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "clang/Frontend/CompilerInstance.h"
Expand All @@ -15,17 +15,18 @@

using namespace clang::ast_matchers;

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

namespace {
const char DiagWording[] =
"do not call %0; consider using exception handling instead";

class SetJmpMacroCallbacks : public PPCallbacks {
SetLongJmpCheck &Check;
AvoidSetjmpLongjmpCheck &Check;

public:
explicit SetJmpMacroCallbacks(SetLongJmpCheck &Check) : Check(Check) {}
explicit SetJmpMacroCallbacks(AvoidSetjmpLongjmpCheck &Check)
: Check(Check) {}

void MacroExpands(const Token &MacroNameTok, const MacroDefinition &MD,
SourceRange Range, const MacroArgs *Args) override {
Expand All @@ -39,15 +40,14 @@ class SetJmpMacroCallbacks : public PPCallbacks {
};
} // namespace

void SetLongJmpCheck::registerPPCallbacks(const SourceManager &SM,
Preprocessor *PP,
Preprocessor *ModuleExpanderPP) {
void AvoidSetjmpLongjmpCheck::registerPPCallbacks(
const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) {
// Per [headers]p5, setjmp must be exposed as a macro instead of a function,
// despite the allowance in C for setjmp to also be an extern function.
PP->addPPCallbacks(std::make_unique<SetJmpMacroCallbacks>(*this));
}

void SetLongJmpCheck::registerMatchers(MatchFinder *Finder) {
void AvoidSetjmpLongjmpCheck::registerMatchers(MatchFinder *Finder) {
// In case there is an implementation that happens to define setjmp as a
// function instead of a macro, this will also catch use of it. However, we
// are primarily searching for uses of longjmp.
Expand All @@ -57,9 +57,9 @@ void SetLongJmpCheck::registerMatchers(MatchFinder *Finder) {
this);
}

void SetLongJmpCheck::check(const MatchFinder::MatchResult &Result) {
void AvoidSetjmpLongjmpCheck::check(const MatchFinder::MatchResult &Result) {
const auto *E = Result.Nodes.getNodeAs<CallExpr>("expr");
diag(E->getExprLoc(), DiagWording) << cast<NamedDecl>(E->getCalleeDecl());
}

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

#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_SETLONGJMPCHECK_H
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_SETLONGJMPCHECK_H
#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_AVOIDSETJMPLONGJMPCHECK_H
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_AVOIDSETJMPLONGJMPCHECK_H

#include "../ClangTidyCheck.h"

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

/// Guards against use of setjmp/longjmp in C++ code
///
/// For the user-facing documentation see:
/// http://clang.llvm.org/extra/clang-tidy/checks/cert/err52-cpp.html
class SetLongJmpCheck : public ClangTidyCheck {
/// http://clang.llvm.org/extra/clang-tidy/checks/bugprone/avoid-setjmp-longjmp.html
class AvoidSetjmpLongjmpCheck : public ClangTidyCheck {
public:
SetLongJmpCheck(StringRef Name, ClangTidyContext *Context)
AvoidSetjmpLongjmpCheck(StringRef Name, ClangTidyContext *Context)
: ClangTidyCheck(Name, Context) {}
bool isLanguageVersionSupported(const LangOptions &LangOpts) const override {
return LangOpts.CPlusPlus;
Expand All @@ -30,6 +30,6 @@ class SetLongJmpCheck : public ClangTidyCheck {
Preprocessor *ModuleExpanderPP) override;
};

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

#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_SETLONGJMPCHECK_H
#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_AVOIDSETJMPLONGJMPCHECK_H
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 @@ -12,6 +12,7 @@
#include "ArgumentCommentCheck.h"
#include "AssertSideEffectCheck.h"
#include "AssignmentInIfConditionCheck.h"
#include "AvoidSetjmpLongjmpCheck.h"
#include "BadSignalToKillThreadCheck.h"
#include "BitwisePointerCastCheck.h"
#include "BoolPointerImplicitConversionCheck.h"
Expand Down Expand Up @@ -116,6 +117,8 @@ class BugproneModule : public ClangTidyModule {
"bugprone-assert-side-effect");
CheckFactories.registerCheck<AssignmentInIfConditionCheck>(
"bugprone-assignment-in-if-condition");
CheckFactories.registerCheck<AvoidSetjmpLongjmpCheck>(
"bugprone-avoid-setjmp-longjmp");
CheckFactories.registerCheck<BadSignalToKillThreadCheck>(
"bugprone-bad-signal-to-kill-thread");
CheckFactories.registerCheck<BitwisePointerCastCheck>(
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 @@ -7,6 +7,7 @@ add_clang_library(clangTidyBugproneModule STATIC
ArgumentCommentCheck.cpp
AssertSideEffectCheck.cpp
AssignmentInIfConditionCheck.cpp
AvoidSetjmpLongjmpCheck.cpp
BadSignalToKillThreadCheck.cpp
BitwisePointerCastCheck.cpp
BoolPointerImplicitConversionCheck.cpp
Expand Down
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 @@ -9,6 +9,7 @@
#include "../ClangTidy.h"
#include "../ClangTidyModule.h"
#include "../ClangTidyModuleRegistry.h"
#include "../bugprone/AvoidSetjmpLongjmpCheck.h"
#include "../bugprone/BadSignalToKillThreadCheck.h"
#include "../bugprone/PointerArithmeticOnPolymorphicObjectCheck.h"
#include "../bugprone/ReservedIdentifierCheck.h"
Expand Down Expand Up @@ -38,7 +39,6 @@
#include "MutatingCopyCheck.h"
#include "NonTrivialTypesLibcMemoryCallsCheck.h"
#include "ProperlySeededRandomGeneratorCheck.h"
#include "SetLongJmpCheck.h"
#include "StaticObjectExceptionCheck.h"
#include "ThrownExceptionTypeCheck.h"
#include "VariadicFunctionDefCheck.h"
Expand Down Expand Up @@ -256,7 +256,8 @@ class CERTModule : public ClangTidyModule {
// ERR
CheckFactories.registerCheck<misc::ThrowByValueCatchByReferenceCheck>(
"cert-err09-cpp");
CheckFactories.registerCheck<SetLongJmpCheck>("cert-err52-cpp");
CheckFactories.registerCheck<bugprone::AvoidSetjmpLongjmpCheck>(
"cert-err52-cpp");
CheckFactories.registerCheck<StaticObjectExceptionCheck>("cert-err58-cpp");
CheckFactories.registerCheck<ThrownExceptionTypeCheck>("cert-err60-cpp");
CheckFactories.registerCheck<misc::ThrowByValueCatchByReferenceCheck>(
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 @@ -13,7 +13,6 @@ add_clang_library(clangTidyCERTModule STATIC
MutatingCopyCheck.cpp
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-err52-cpp <clang-tidy/checks/cert/err52-cpp>` to
:doc:`bugprone-avoid-setjmp-longjmp
<clang-tidy/checks/bugprone/avoid-setjmp-longjmp>`
keeping initial check as an alias to the new one.

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

Expand Down
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated docs to fix the broken external CERT link (ERR52-CPP).

Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
.. title:: clang-tidy - bugprone-avoid-setjmp-longjmp

bugprone-avoid-setjmp-longjmp
=============================

Flags all call expressions involving ``setjmp()`` and ``longjmp()``.

This check corresponds to the CERT C++ Coding Standard rule
`ERR52-CPP. Do not use setjmp() or longjmp()
<https://www.securecoding.cert.org/confluence/pages/viewpage.action?pageId=88046492>`_.
8 changes: 3 additions & 5 deletions clang-tools-extra/docs/clang-tidy/checks/cert/err52-cpp.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@
cert-err52-cpp
==============

This check flags all call expressions involving ``setjmp()`` and ``longjmp()``.

This check corresponds to the CERT C++ Coding Standard rule
`ERR52-CPP. Do not use setjmp() or longjmp()
<https://www.securecoding.cert.org/confluence/pages/viewpage.action?pageId=1834>`_.
The cert-err52-cpp check is an alias, please see
`bugprone-avoid-setjmp-longjmp <../bugprone/avoid-setjmp-longjmp.html>`_
for more information.
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 @@ -80,6 +80,7 @@ Clang-Tidy Checks
:doc:`bugprone-argument-comment <bugprone/argument-comment>`, "Yes"
:doc:`bugprone-assert-side-effect <bugprone/assert-side-effect>`,
:doc:`bugprone-assignment-in-if-condition <bugprone/assignment-in-if-condition>`,
:doc:`bugprone-avoid-setjmp-longjmp <bugprone/avoid-setjmp-longjmp>`,
:doc:`bugprone-bad-signal-to-kill-thread <bugprone/bad-signal-to-kill-thread>`,
:doc:`bugprone-bitwise-pointer-cast <bugprone/bitwise-pointer-cast>`,
:doc:`bugprone-bool-pointer-implicit-conversion <bugprone/bool-pointer-implicit-conversion>`, "Yes"
Expand Down Expand Up @@ -175,7 +176,6 @@ Clang-Tidy Checks
:doc:`cert-dcl58-cpp <cert/dcl58-cpp>`,
: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>`,
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-err52-cpp <cert/err52-cpp>`, :doc:`bugprone-avoid-setjmp-longjmp <bugprone/avoid-setjmp-longjmp>`,
: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,4 +1,4 @@
// RUN: %check_clang_tidy %s cert-err52-cpp %t
// RUN: %check_clang_tidy %s bugprone-avoid-setjmp-longjmp %t

typedef void *jmp_buf;
extern int __setjmpimpl(jmp_buf);
Expand All @@ -13,7 +13,7 @@ using ::longjmp;
static jmp_buf env;
void g() {
std::longjmp(env, 1);
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not call 'longjmp'; consider using exception handling instead [cert-err52-cpp]
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not call 'longjmp'; consider using exception handling instead [bugprone-avoid-setjmp-longjmp]
::longjmp(env, 1);
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not call 'longjmp'; consider using exception handling instead
longjmp(env, 1);
Expand Down