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
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 @@ -73,6 +73,7 @@
#include "SizeofExpressionCheck.h"
#include "SpuriouslyWakeUpFunctionsCheck.h"
#include "StandaloneEmptyCheck.h"
#include "StdNamespaceModificationCheck.h"
#include "StringConstructorCheck.h"
#include "StringIntegerAssignmentCheck.h"
#include "StringLiteralWithEmbeddedNulCheck.h"
Expand Down Expand Up @@ -237,6 +238,8 @@ class BugproneModule : public ClangTidyModule {
"bugprone-spuriously-wake-up-functions");
CheckFactories.registerCheck<StandaloneEmptyCheck>(
"bugprone-standalone-empty");
CheckFactories.registerCheck<StdNamespaceModificationCheck>(
"bugprone-std-namespace-modification");
CheckFactories.registerCheck<StringConstructorCheck>(
"bugprone-string-constructor");
CheckFactories.registerCheck<StringIntegerAssignmentCheck>(
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 @@ -75,6 +75,7 @@ add_clang_library(clangTidyBugproneModule STATIC
SmartPtrArrayMismatchCheck.cpp
SpuriouslyWakeUpFunctionsCheck.cpp
StandaloneEmptyCheck.cpp
StdNamespaceModificationCheck.cpp
StringConstructorCheck.cpp
StringIntegerAssignmentCheck.cpp
StringLiteralWithEmbeddedNulCheck.cpp
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
//
//===----------------------------------------------------------------------===//

#include "DontModifyStdNamespaceCheck.h"
#include "StdNamespaceModificationCheck.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "clang/ASTMatchers/ASTMatchersInternal.h"

Expand Down Expand Up @@ -36,9 +36,9 @@ AST_POLYMORPHIC_MATCHER_P(

} // namespace

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

void DontModifyStdNamespaceCheck::registerMatchers(MatchFinder *Finder) {
void StdNamespaceModificationCheck::registerMatchers(MatchFinder *Finder) {
auto HasStdParent =
hasDeclContext(namespaceDecl(hasAnyName("std", "posix"),
unless(hasParent(namespaceDecl())))
Expand Down Expand Up @@ -96,7 +96,7 @@ void DontModifyStdNamespaceCheck::registerMatchers(MatchFinder *Finder) {
.bind("decl"),
this);
}
} // namespace clang::tidy::cert
} // namespace clang::tidy::bugprone

static const NamespaceDecl *getTopLevelLexicalNamespaceDecl(const Decl *D) {
const NamespaceDecl *LastNS = nullptr;
Expand All @@ -108,7 +108,7 @@ static const NamespaceDecl *getTopLevelLexicalNamespaceDecl(const Decl *D) {
return LastNS;
}

void clang::tidy::cert::DontModifyStdNamespaceCheck::check(
void clang::tidy::bugprone::StdNamespaceModificationCheck::check(
const MatchFinder::MatchResult &Result) {
const auto *D = Result.Nodes.getNodeAs<Decl>("decl");
const auto *NS = Result.Nodes.getNodeAs<NamespaceDecl>("nmspc");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,21 @@
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CERT_DONT_MODIFY_STD_NAMESPACE_H
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CERT_DONT_MODIFY_STD_NAMESPACE_H
#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_STDNAMESPACEMODIFICATIONCHECK_H
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_STDNAMESPACEMODIFICATIONCHECK_H

#include "../ClangTidyCheck.h"

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

/// Modification of the std or posix namespace can result in undefined behavior.
/// This check warns for such modifications.
///
/// For the user-facing documentation see:
/// https://clang.llvm.org/extra/clang-tidy/checks/cert/dcl58-cpp.html
class DontModifyStdNamespaceCheck : public ClangTidyCheck {
/// https://clang.llvm.org/extra/clang-tidy/checks/bugprone/std-namespace-modification.html
class StdNamespaceModificationCheck : public ClangTidyCheck {
public:
DontModifyStdNamespaceCheck(StringRef Name, ClangTidyContext *Context)
StdNamespaceModificationCheck(StringRef Name, ClangTidyContext *Context)
: ClangTidyCheck(Name, Context) {}
bool isLanguageVersionSupported(const LangOptions &LangOpts) const override {
return LangOpts.CPlusPlus;
Expand All @@ -29,6 +29,6 @@ class DontModifyStdNamespaceCheck : 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_DONT_MODIFY_STD_NAMESPACE_H
#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_STDNAMESPACEMODIFICATIONCHECK_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 @@ -19,6 +19,7 @@
#include "../bugprone/SignedCharMisuseCheck.h"
#include "../bugprone/SizeofExpressionCheck.h"
#include "../bugprone/SpuriouslyWakeUpFunctionsCheck.h"
#include "../bugprone/StdNamespaceModificationCheck.h"
#include "../bugprone/SuspiciousMemoryComparisonCheck.h"
#include "../bugprone/ThrowingStaticInitializationCheck.h"
#include "../bugprone/UncheckedStringToNumberConversionCheck.h"
Expand All @@ -36,7 +37,6 @@
#include "../performance/MoveConstructorInitCheck.h"
#include "../readability/EnumInitialValueCheck.h"
#include "../readability/UppercaseLiteralSuffixCheck.h"
#include "DontModifyStdNamespaceCheck.h"
#include "FloatLoopCounter.h"
#include "LimitedRandomnessCheck.h"
#include "MutatingCopyCheck.h"
Expand Down Expand Up @@ -251,7 +251,8 @@ class CERTModule : public ClangTidyModule {
"cert-dcl51-cpp");
CheckFactories.registerCheck<misc::NewDeleteOverloadsCheck>(
"cert-dcl54-cpp");
CheckFactories.registerCheck<DontModifyStdNamespaceCheck>("cert-dcl58-cpp");
CheckFactories.registerCheck<bugprone::StdNamespaceModificationCheck>(
"cert-dcl58-cpp");
CheckFactories.registerCheck<google::build::UnnamedNamespaceInHeaderCheck>(
"cert-dcl59-cpp");
// ERR
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 @@ -5,7 +5,6 @@ set(LLVM_LINK_COMPONENTS

add_clang_library(clangTidyCERTModule STATIC
CERTTidyModule.cpp
DontModifyStdNamespaceCheck.cpp
FloatLoopCounter.cpp
LimitedRandomnessCheck.cpp
MutatingCopyCheck.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 @@ -244,6 +244,11 @@ New check aliases
<clang-tidy/checks/modernize/avoid-variadic-functions>`
keeping initial check as an alias to the new one.

- Renamed :doc:`cert-dcl58-cpp <clang-tidy/checks/cert/dcl58-cpp>` to
:doc:`bugprone-std-namespace-modification
<clang-tidy/checks/bugprone/std-namespace-modification>`
keeping initial check as an alias to the new one.

- Renamed :doc:`cert-env33-c <clang-tidy/checks/cert/env33-c>` to
:doc:`bugprone-command-processor
<clang-tidy/checks/bugprone/command-processor>`
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
.. title:: clang-tidy - bugprone-std-namespace-modification

bugprone-std-namespace-modification
===================================

Warns on modifications of the ``std`` or ``posix`` namespaces which can
result in undefined behavior.

The ``std`` (or ``posix``) namespace is allowed to be extended with (class or
function) template specializations that depend on an user-defined type (a type
that is not defined in the standard system headers).

The check detects the following (user provided) declarations in namespace ``std`` or ``posix``:

- Anything that is not a template specialization.
- Explicit specializations of any standard library function template or class template, if it does not have any user-defined type as template argument.
- Explicit specializations of any member function of a standard library class template.
- Explicit specializations of any member function template of a standard library class or class template.
- Explicit or partial specialization of any member class template of a standard library class or class template.

Examples:

.. code-block:: c++

namespace std {
int x; // warning: modification of 'std' namespace can result in undefined behavior [bugprone-dont-modify-std-namespace]
}

namespace posix::a { // warning: modification of 'posix' namespace can result in undefined behavior
}

template <>
struct ::std::hash<long> { // warning: modification of 'std' namespace can result in undefined behavior
unsigned long operator()(const long &K) const {
return K;
}
};

struct MyData { long data; };

template <>
struct ::std::hash<MyData> { // no warning: specialization with user-defined type
unsigned long operator()(const MyData &K) const {
return K.data;
}
};

namespace std {
template <>
void swap<bool>(bool &a, bool &b); // warning: modification of 'std' namespace can result in undefined behavior

template <>
bool less<void>::operator()<MyData &&, MyData &&>(MyData &&, MyData &&) const { // warning: modification of 'std' namespace can result in undefined behavior
return true;
}
}

References
----------

This check corresponds to the CERT C++ Coding Standard rule
`DCL58-CPP. Do not modify the standard namespaces
<https://www.securecoding.cert.org/confluence/display/cplusplus/DCL58-CPP.+Do+not+modify+the+standard+namespaces>`_.
54 changes: 3 additions & 51 deletions clang-tools-extra/docs/clang-tidy/checks/cert/dcl58-cpp.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,57 +3,9 @@
cert-dcl58-cpp
==============

Modification of the ``std`` or ``posix`` namespace can result in undefined
behavior.
This check warns for such modifications.
The ``std`` (or ``posix``) namespace is allowed to be extended with (class or
function) template specializations that depend on an user-defined type (a type
that is not defined in the standard system headers).

The check detects the following (user provided) declarations in namespace ``std`` or ``posix``:

- Anything that is not a template specialization.
- Explicit specializations of any standard library function template or class template, if it does not have any user-defined type as template argument.
- Explicit specializations of any member function of a standard library class template.
- Explicit specializations of any member function template of a standard library class or class template.
- Explicit or partial specialization of any member class template of a standard library class or class template.

Examples:

.. code-block:: c++

namespace std {
int x; // warning: modification of 'std' namespace can result in undefined behavior [cert-dcl58-cpp]
}

namespace posix::a { // warning: modification of 'posix' namespace can result in undefined behavior
}

template <>
struct ::std::hash<long> { // warning: modification of 'std' namespace can result in undefined behavior
unsigned long operator()(const long &K) const {
return K;
}
};

struct MyData { long data; };

template <>
struct ::std::hash<MyData> { // no warning: specialization with user-defined type
unsigned long operator()(const MyData &K) const {
return K.data;
}
};

namespace std {
template <>
void swap<bool>(bool &a, bool &b); // warning: modification of 'std' namespace can result in undefined behavior

template <>
bool less<void>::operator()<MyData &&, MyData &&>(MyData &&, MyData &&) const { // warning: modification of 'std' namespace can result in undefined behavior
return true;
}
}
The `cert-dcl58-cpp` is an aliaes, please see
`bugprone-std-namespace-modification <../bugprone/std-namespace-modification.html>`_
for more information.

This check corresponds to the CERT C++ Coding Standard rule
`DCL58-CPP. Do not modify the standard namespaces
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 @@ -141,6 +141,7 @@ Clang-Tidy Checks
:doc:`bugprone-sizeof-expression <bugprone/sizeof-expression>`,
:doc:`bugprone-spuriously-wake-up-functions <bugprone/spuriously-wake-up-functions>`,
:doc:`bugprone-standalone-empty <bugprone/standalone-empty>`, "Yes"
:doc:`bugprone-std-namespace-modification <bugprone/std-namespace-modification>`,
:doc:`bugprone-string-constructor <bugprone/string-constructor>`, "Yes"
:doc:`bugprone-string-integer-assignment <bugprone/string-integer-assignment>`, "Yes"
:doc:`bugprone-string-literal-with-embedded-nul <bugprone/string-literal-with-embedded-nul>`,
Expand Down Expand Up @@ -175,7 +176,6 @@ Clang-Tidy Checks
:doc:`bugprone-unused-return-value <bugprone/unused-return-value>`,
:doc:`bugprone-use-after-move <bugprone/use-after-move>`,
:doc:`bugprone-virtual-near-miss <bugprone/virtual-near-miss>`, "Yes"
:doc:`cert-dcl58-cpp <cert/dcl58-cpp>`,
:doc:`cert-err33-c <cert/err33-c>`,
:doc:`cert-err60-cpp <cert/err60-cpp>`,
:doc:`cert-flp30-c <cert/flp30-c>`,
Expand Down Expand Up @@ -441,6 +441,7 @@ Check aliases
:doc:`cert-dcl50-cpp <cert/dcl50-cpp>`, :doc:`modernize-avoid-variadic-functions <modernize/avoid-variadic-functions>`,
:doc:`cert-dcl51-cpp <cert/dcl51-cpp>`, :doc:`bugprone-reserved-identifier <bugprone/reserved-identifier>`, "Yes"
:doc:`cert-dcl54-cpp <cert/dcl54-cpp>`, :doc:`misc-new-delete-overloads <misc/new-delete-overloads>`,
:doc:`cert-dcl58-cpp <cert/dcl58-cpp>`, :doc:`bugprone-std-namespace-modification <bugprone/std-namespace-modification>`,
:doc:`cert-dcl59-cpp <cert/dcl59-cpp>`, :doc:`google-build-namespaces <google/build-namespaces>`,
:doc:`cert-env33-c <cert/env33-c>`, :doc:`bugprone-command-processor <bugprone/command-processor>`,
:doc:`cert-err09-cpp <cert/err09-cpp>`, :doc:`misc-throw-by-value-catch-by-reference <misc/throw-by-value-catch-by-reference>`,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ struct X {};
} // namespace std

// Template specializations that are in a system-header file.
// The purpose is to test cert-dcl58-cpp (no warnings here).
// The purpose is to test bugprone-std-namespace-modification (no warnings here).
namespace std {
template <>
void swap<short>(short &, short &){};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// RUN: %check_clang_tidy -std=c++17-or-later %s cert-dcl58-cpp %t -- -- -I %clang_tidy_headers
// RUN: %check_clang_tidy -std=c++17-or-later %s bugprone-std-namespace-modification %t -- -- -I %clang_tidy_headers

#include "system-header-simulation.h"

Expand All @@ -15,7 +15,7 @@ namespace A {
}

namespace posix {
// CHECK-MESSAGES: :[[@LINE+2]]:11: warning: modification of 'posix' namespace can result in undefined behavior [cert-dcl58-cpp]
// CHECK-MESSAGES: :[[@LINE+2]]:11: warning: modification of 'posix' namespace can result in undefined behavior [bugprone-std-namespace-modification]
// CHECK-MESSAGES: :[[@LINE-2]]:11: note: 'posix' namespace opened here
namespace foo {
int foobar;
Expand Down