Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 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 @@ -71,6 +71,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 @@ -231,6 +232,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 @@ -73,6 +73,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 @@ -17,6 +17,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 @@ -35,7 +36,6 @@
#include "../readability/EnumInitialValueCheck.h"
#include "../readability/UppercaseLiteralSuffixCheck.h"
#include "DefaultOperatorNewAlignmentCheck.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 @@ -6,7 +6,6 @@ set(LLVM_LINK_COMPONENTS
add_clang_library(clangTidyCERTModule STATIC
CERTTidyModule.cpp
DefaultOperatorNewAlignmentCheck.cpp
DontModifyStdNamespaceCheck.cpp
FloatLoopCounter.cpp
LimitedRandomnessCheck.cpp
MutatingCopyCheck.cpp
Expand Down
7 changes: 6 additions & 1 deletion 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 Expand Up @@ -367,7 +372,7 @@ Changes in existing checks

- Improved :doc:`misc-const-correctness
<clang-tidy/checks/misc/const-correctness>` check to avoid false
positives when pointers is transferred to non-const references
positives when pointers is transferred to non-const references
and avoid false positives of function pointer and fix false
positives on return of non-const pointer.

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 @@ -139,6 +139,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 @@ -173,7 +174,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-err09-cpp <cert/err09-cpp>`, :doc:`misc-throw-by-value-catch-by-reference <misc/throw-by-value-catch-by-reference>`,
:doc:`cert-env33-c <cert/env33-c>`, :doc:`bugprone-command-processor <bugprone/command-processor>`,
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