SERVER-71744 Move atomic, mutex and nonmongo assert to clang-tidy
This commit is contained in:
parent
a66abc65d6
commit
28c4056019
@ -35,6 +35,9 @@ Checks: '-*,
|
||||
modernize-unary-static-assert,
|
||||
mongo-cctype-check,
|
||||
mongo-header-bracket-check,
|
||||
mongo-std-atomic-check,
|
||||
mongo-mutex-check,
|
||||
mongo-assert-check,
|
||||
mongo-std-optional-check,
|
||||
mongo-uninterruptible-lock-guard-check,
|
||||
mongo-volatile-check,
|
||||
|
||||
@ -54,8 +54,6 @@ _RE_LINT = re.compile("//.*NOLINT")
|
||||
_RE_COMMENT_STRIP = re.compile("//.*")
|
||||
|
||||
_RE_PATTERN_MONGO_POLYFILL = _make_polyfill_regex()
|
||||
_RE_MUTEX = re.compile('(^|[ ({,])stdx?::mutex[ ({]')
|
||||
_RE_ASSERT = re.compile(r'\bassert\s*\(')
|
||||
_RE_UNSTRUCTURED_LOG = re.compile(r'\blogd\s*\(')
|
||||
_RE_COLLECTION_SHARDING_RUNTIME = re.compile(r'\bCollectionShardingRuntime\b')
|
||||
_RE_RAND = re.compile(r'\b(srand\(|rand\(\))')
|
||||
@ -153,9 +151,6 @@ class Linter:
|
||||
continue
|
||||
|
||||
self._check_for_mongo_polyfill(linenum)
|
||||
self._check_for_mongo_atomic(linenum)
|
||||
self._check_for_mongo_mutex(linenum)
|
||||
self._check_for_nonmongo_assert(linenum)
|
||||
self._check_for_mongo_unstructured_log(linenum)
|
||||
self._check_for_mongo_config_header(linenum)
|
||||
self._check_for_collection_sharding_runtime(linenum)
|
||||
@ -240,29 +235,6 @@ class Linter:
|
||||
'Illegal use of banned name from std::/boost:: for "%s", use mongo::stdx:: variant instead'
|
||||
% (match.group(0)))
|
||||
|
||||
def _check_for_mongo_atomic(self, linenum):
|
||||
line = self.clean_lines[linenum]
|
||||
if 'std::atomic' in line:
|
||||
self._error(
|
||||
linenum, 'mongodb/stdatomic',
|
||||
'Illegal use of prohibited std::atomic<T>, use AtomicWord<T> or other types '
|
||||
'from "mongo/platform/atomic_word.h"')
|
||||
|
||||
def _check_for_mongo_mutex(self, linenum):
|
||||
line = self.clean_lines[linenum]
|
||||
if _RE_MUTEX.search(line):
|
||||
self._error(
|
||||
linenum, 'mongodb/stdxmutex', 'Illegal use of prohibited stdx::mutex, '
|
||||
'use mongo::Mutex from mongo/platform/mutex.h instead.')
|
||||
|
||||
def _check_for_nonmongo_assert(self, linenum):
|
||||
line = self.clean_lines[linenum]
|
||||
if _RE_ASSERT.search(line):
|
||||
self._error(
|
||||
linenum, 'mongodb/assert',
|
||||
'Illegal use of the bare assert function, use a function from assert_utils.h instead.'
|
||||
)
|
||||
|
||||
def _check_for_mongo_unstructured_log(self, linenum):
|
||||
line = self.clean_lines[linenum]
|
||||
if _RE_UNSTRUCTURED_LOG.search(line) or 'doUnstructuredLogImpl' in line:
|
||||
|
||||
@ -109,7 +109,7 @@ class BSONLexer;
|
||||
#include <typeinfo>
|
||||
#ifndef YY_ASSERT
|
||||
#include <cassert>
|
||||
#define YY_ASSERT assert
|
||||
#define YY_ASSERT assert // NOLINT(mongo-assert-check)
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@ -60,7 +60,7 @@ private:
|
||||
|
||||
BackendTraits(boost::shared_ptr<backend_t> backend) : _backend(std::move(backend)) {}
|
||||
boost::shared_ptr<backend_t> _backend;
|
||||
backend_mutex_type _mutex;
|
||||
backend_mutex_type _mutex; // NOLINT(mongo-mutex-check)
|
||||
std::function<bool(boost::log::attribute_value_set const&)> _filter;
|
||||
};
|
||||
|
||||
|
||||
83
src/mongo/tools/mongo_tidy_checks/MongoAssertCheck.cpp
Normal file
83
src/mongo/tools/mongo_tidy_checks/MongoAssertCheck.cpp
Normal file
@ -0,0 +1,83 @@
|
||||
/**
|
||||
* Copyright (C) 2023-present MongoDB, Inc.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the Server Side Public License, version 1,
|
||||
* as published by MongoDB, Inc.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* Server Side Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the Server Side Public License
|
||||
* along with this program. If not, see
|
||||
* <http://www.mongodb.com/licensing/server-side-public-license>.
|
||||
*
|
||||
* As a special exception, the copyright holders give permission to link the
|
||||
* code of portions of this program with the OpenSSL library under certain
|
||||
* conditions as described in each individual source file and distribute
|
||||
* linked combinations including the program with the OpenSSL library. You
|
||||
* must comply with the Server Side Public License in all respects for
|
||||
* all of the code used other than as permitted herein. If you modify file(s)
|
||||
* with this exception, you may extend this exception to your version of the
|
||||
* file(s), but you are not obligated to do so. If you do not wish to do so,
|
||||
* delete this exception statement from your version. If you delete this
|
||||
* exception statement from all source files in the program, then also delete
|
||||
* it in the license file.
|
||||
*/
|
||||
|
||||
#include "MongoAssertCheck.h"
|
||||
|
||||
#include <clang/Lex/Lexer.h>
|
||||
|
||||
namespace mongo::tidy {
|
||||
|
||||
using namespace clang;
|
||||
using namespace clang::ast_matchers;
|
||||
|
||||
MongoAssertCheck::MongoAssertCheck(StringRef Name, clang::tidy::ClangTidyContext* Context)
|
||||
: ClangTidyCheck(Name, Context) {}
|
||||
|
||||
// Custom AST Matcher that checks if an expression is an 'assert' macro expansion
|
||||
AST_MATCHER(Expr, isAssertMacroExpansion) {
|
||||
|
||||
// Return false if the expression is not a macro expansion
|
||||
if (!Node.getBeginLoc().isMacroID()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto& SM = Finder->getASTContext().getSourceManager();
|
||||
auto MacroLoc = SM.getImmediateMacroCallerLoc(Node.getBeginLoc());
|
||||
|
||||
// Get the name of the macro being expanded
|
||||
llvm::StringRef MacroSpellingRef =
|
||||
clang::Lexer::getImmediateMacroName(MacroLoc, SM, Finder->getASTContext().getLangOpts());
|
||||
std::string Spelling = MacroSpellingRef.str();
|
||||
|
||||
if (Spelling == "assert") {
|
||||
// Check if the file name contains "assert.h"
|
||||
// <cassert> will also be caught because it redirects to assert.h
|
||||
auto FileName = SM.getFilename(SM.getSpellingLoc(MacroLoc));
|
||||
return llvm::StringRef(FileName).contains("assert.h");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void MongoAssertCheck::registerMatchers(ast_matchers::MatchFinder* Finder) {
|
||||
|
||||
// Add the custom matcher 'isAssertMacroExpansion' to the MatchFinder
|
||||
Finder->addMatcher(expr(isAssertMacroExpansion()).bind("assertMacroExpansion"), this);
|
||||
}
|
||||
|
||||
void MongoAssertCheck::check(const ast_matchers::MatchFinder::MatchResult& Result) {
|
||||
|
||||
// Check assert macro expansion
|
||||
const auto* AssertMacroExpansion = Result.Nodes.getNodeAs<Expr>("assertMacroExpansion");
|
||||
if (AssertMacroExpansion) {
|
||||
diag(AssertMacroExpansion->getBeginLoc(),
|
||||
"Illegal use of the bare assert function, use a function from assert_util.h instead");
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace mongo::tidy
|
||||
53
src/mongo/tools/mongo_tidy_checks/MongoAssertCheck.h
Normal file
53
src/mongo/tools/mongo_tidy_checks/MongoAssertCheck.h
Normal file
@ -0,0 +1,53 @@
|
||||
/**
|
||||
* Copyright (C) 2023-present MongoDB, Inc.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the Server Side Public License, version 1,
|
||||
* as published by MongoDB, Inc.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* Server Side Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the Server Side Public License
|
||||
* along with this program. If not, see
|
||||
* <http://www.mongodb.com/licensing/server-side-public-license>.
|
||||
*
|
||||
* As a special exception, the copyright holders give permission to link the
|
||||
* code of portions of this program with the OpenSSL library under certain
|
||||
* conditions as described in each individual source file and distribute
|
||||
* linked combinations including the program with the OpenSSL library. You
|
||||
* must comply with the Server Side Public License in all respects for
|
||||
* all of the code used other than as permitted herein. If you modify file(s)
|
||||
* with this exception, you may extend this exception to your version of the
|
||||
* file(s), but you are not obligated to do so. If you do not wish to do so,
|
||||
* delete this exception statement from your version. If you delete this
|
||||
* exception statement from all source files in the program, then also delete
|
||||
* it in the license file.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <clang-tidy/ClangTidy.h>
|
||||
#include <clang-tidy/ClangTidyCheck.h>
|
||||
|
||||
namespace mongo::tidy {
|
||||
|
||||
/**
|
||||
* MongoAssertCheck is a custom clang-tidy check for detecting
|
||||
* the usage of nonmongo assert in the source code.
|
||||
*
|
||||
* It extends ClangTidyCheck and overrides the registerMatchers
|
||||
* and check functions. The registerMatchers function adds matchers
|
||||
* to identify the usage of nongmongo assert, while
|
||||
* the check function flags the matched occurrences
|
||||
*/
|
||||
class MongoAssertCheck : public clang::tidy::ClangTidyCheck {
|
||||
|
||||
public:
|
||||
MongoAssertCheck(clang::StringRef Name, clang::tidy::ClangTidyContext* Context);
|
||||
void registerMatchers(clang::ast_matchers::MatchFinder* Finder) override;
|
||||
void check(const clang::ast_matchers::MatchFinder::MatchResult& Result) override;
|
||||
};
|
||||
|
||||
} // namespace mongo::tidy
|
||||
77
src/mongo/tools/mongo_tidy_checks/MongoMutexCheck.cpp
Normal file
77
src/mongo/tools/mongo_tidy_checks/MongoMutexCheck.cpp
Normal file
@ -0,0 +1,77 @@
|
||||
/**
|
||||
* Copyright (C) 2023-present MongoDB, Inc.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the Server Side Public License, version 1,
|
||||
* as published by MongoDB, Inc.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* Server Side Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the Server Side Public License
|
||||
* along with this program. If not, see
|
||||
* <http://www.mongodb.com/licensing/server-side-public-license>.
|
||||
*
|
||||
* As a special exception, the copyright holders give permission to link the
|
||||
* code of portions of this program with the OpenSSL library under certain
|
||||
* conditions as described in each individual source file and distribute
|
||||
* linked combinations including the program with the OpenSSL library. You
|
||||
* must comply with the Server Side Public License in all respects for
|
||||
* all of the code used other than as permitted herein. If you modify file(s)
|
||||
* with this exception, you may extend this exception to your version of the
|
||||
* file(s), but you are not obligated to do so. If you do not wish to do so,
|
||||
* delete this exception statement from your version. If you delete this
|
||||
* exception statement from all source files in the program, then also delete
|
||||
* it in the license file.
|
||||
*/
|
||||
|
||||
#include "MongoMutexCheck.h"
|
||||
|
||||
namespace mongo::tidy {
|
||||
|
||||
using namespace clang;
|
||||
using namespace clang::ast_matchers;
|
||||
|
||||
MongoMutexCheck::MongoMutexCheck(StringRef Name, clang::tidy::ClangTidyContext* Context)
|
||||
: ClangTidyCheck(Name, Context) {}
|
||||
|
||||
void MongoMutexCheck::registerMatchers(ast_matchers::MatchFinder* Finder) {
|
||||
// TODO: SERVER-74929 Remove the NOLINT comment below after we remove _check_for_mongo_polyfill
|
||||
// check from simplecpplint.py
|
||||
// This matcher finds variable declarations (outside of structs/classes) with a type of either
|
||||
// std::mutex or stdx::mutex. It works by matching variable declarations whose type, when
|
||||
// reduced to its canonical form, has a declaration named "::std::mutex".
|
||||
Finder->addMatcher(varDecl(hasType(qualType(hasCanonicalType(
|
||||
hasDeclaration(namedDecl(hasName("::std::mutex"))))))) // NOLINT
|
||||
.bind("mutex_var"),
|
||||
this);
|
||||
|
||||
// This matcher finds field declarations (inside structs/classes) with a type of either
|
||||
// std::mutex or stdx::mutex.
|
||||
Finder->addMatcher(fieldDecl(hasType(qualType(hasCanonicalType(hasDeclaration(
|
||||
namedDecl(hasName("::std::mutex"))))))) // NOLINT
|
||||
.bind("mutex_field"),
|
||||
this);
|
||||
}
|
||||
|
||||
void MongoMutexCheck::check(const ast_matchers::MatchFinder::MatchResult& Result) {
|
||||
|
||||
// Get the matched variable declaration of type std::mutex or stdx::mutex
|
||||
const auto* matchedMutexVar = Result.Nodes.getNodeAs<VarDecl>("mutex_var");
|
||||
if (matchedMutexVar) {
|
||||
diag(matchedMutexVar->getBeginLoc(),
|
||||
"Illegal use of prohibited stdx::mutex, use mongo::Mutex from mongo/platform/mutex.h "
|
||||
"instead.");
|
||||
}
|
||||
|
||||
// Get the matched field declaration of type std::mutex or stdx::mutex
|
||||
const auto* matchedMutexField = Result.Nodes.getNodeAs<FieldDecl>("mutex_field");
|
||||
if (matchedMutexField) {
|
||||
diag(matchedMutexField->getBeginLoc(),
|
||||
"Illegal use of prohibited stdx::mutex, use mongo::Mutex from mongo/platform/mutex.h "
|
||||
"instead.");
|
||||
}
|
||||
}
|
||||
} // namespace mongo::tidy
|
||||
54
src/mongo/tools/mongo_tidy_checks/MongoMutexCheck.h
Normal file
54
src/mongo/tools/mongo_tidy_checks/MongoMutexCheck.h
Normal file
@ -0,0 +1,54 @@
|
||||
/**
|
||||
* Copyright (C) 2023-present MongoDB, Inc.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the Server Side Public License, version 1,
|
||||
* as published by MongoDB, Inc.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* Server Side Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the Server Side Public License
|
||||
* along with this program. If not, see
|
||||
* <http://www.mongodb.com/licensing/server-side-public-license>.
|
||||
*
|
||||
* As a special exception, the copyright holders give permission to link the
|
||||
* code of portions of this program with the OpenSSL library under certain
|
||||
* conditions as described in each individual source file and distribute
|
||||
* linked combinations including the program with the OpenSSL library. You
|
||||
* must comply with the Server Side Public License in all respects for
|
||||
* all of the code used other than as permitted herein. If you modify file(s)
|
||||
* with this exception, you may extend this exception to your version of the
|
||||
* file(s), but you are not obligated to do so. If you do not wish to do so,
|
||||
* delete this exception statement from your version. If you delete this
|
||||
* exception statement from all source files in the program, then also delete
|
||||
* it in the license file.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <clang-tidy/ClangTidy.h>
|
||||
#include <clang-tidy/ClangTidyCheck.h>
|
||||
|
||||
namespace mongo::tidy {
|
||||
|
||||
/**
|
||||
* MongoMutexCheck is a custom clang-tidy check for detecting
|
||||
* the usage of std::mutex and stdx::mutex in the source code.
|
||||
*
|
||||
* It extends ClangTidyCheck and overrides the registerMatchers
|
||||
* and check functions. The registerMatchers function adds matchers
|
||||
* to identify the usage of std::mutex and stdx::mutex, while
|
||||
* the check function flags the matched occurrences for further
|
||||
* analysis or modification.
|
||||
*/
|
||||
class MongoMutexCheck : public clang::tidy::ClangTidyCheck {
|
||||
|
||||
public:
|
||||
MongoMutexCheck(clang::StringRef Name, clang::tidy::ClangTidyContext* Context);
|
||||
void registerMatchers(clang::ast_matchers::MatchFinder* Finder) override;
|
||||
void check(const clang::ast_matchers::MatchFinder::MatchResult& Result) override;
|
||||
};
|
||||
|
||||
} // namespace mongo::tidy
|
||||
63
src/mongo/tools/mongo_tidy_checks/MongoStdAtomicCheck.cpp
Normal file
63
src/mongo/tools/mongo_tidy_checks/MongoStdAtomicCheck.cpp
Normal file
@ -0,0 +1,63 @@
|
||||
/**
|
||||
* Copyright (C) 2023-present MongoDB, Inc.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the Server Side Public License, version 1,
|
||||
* as published by MongoDB, Inc.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* Server Side Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the Server Side Public License
|
||||
* along with this program. If not, see
|
||||
* <http://www.mongodb.com/licensing/server-side-public-license>.
|
||||
*
|
||||
* As a special exception, the copyright holders give permission to link the
|
||||
* code of portions of this program with the OpenSSL library under certain
|
||||
* conditions as described in each individual source file and distribute
|
||||
* linked combinations including the program with the OpenSSL library. You
|
||||
* must comply with the Server Side Public License in all respects for
|
||||
* all of the code used other than as permitted herein. If you modify file(s)
|
||||
* with this exception, you may extend this exception to your version of the
|
||||
* file(s), but you are not obligated to do so. If you do not wish to do so,
|
||||
* delete this exception statement from your version. If you delete this
|
||||
* exception statement from all source files in the program, then also delete
|
||||
* it in the license file.
|
||||
*/
|
||||
|
||||
#include "MongoStdAtomicCheck.h"
|
||||
#include "MongoTidyUtils.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
namespace mongo::tidy {
|
||||
|
||||
using namespace clang;
|
||||
using namespace clang::ast_matchers;
|
||||
|
||||
MongoStdAtomicCheck::MongoStdAtomicCheck(StringRef Name, clang::tidy::ClangTidyContext* Context)
|
||||
: ClangTidyCheck(Name, Context) {}
|
||||
|
||||
void MongoStdAtomicCheck::registerMatchers(ast_matchers::MatchFinder* Finder) {
|
||||
|
||||
// match parameter decl, variable Decl, Field Decl, Reference Decl, Template Decl regarding
|
||||
// std::atomic
|
||||
Finder->addMatcher(loc(templateSpecializationType(
|
||||
hasDeclaration(namedDecl(hasName("atomic"), isFromStdNamespace()))))
|
||||
.bind("loc_atomic"),
|
||||
this);
|
||||
}
|
||||
|
||||
void MongoStdAtomicCheck::check(const ast_matchers::MatchFinder::MatchResult& Result) {
|
||||
|
||||
const auto* loc_match = Result.Nodes.getNodeAs<TypeLoc>("loc_atomic");
|
||||
if (loc_match) {
|
||||
diag(loc_match->getBeginLoc(),
|
||||
"Illegal use of prohibited std::atomic<T>, use AtomicWord<T> or other types from "
|
||||
"\"mongo/platform/atomic_word.h\"");
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace mongo::tidy
|
||||
50
src/mongo/tools/mongo_tidy_checks/MongoStdAtomicCheck.h
Normal file
50
src/mongo/tools/mongo_tidy_checks/MongoStdAtomicCheck.h
Normal file
@ -0,0 +1,50 @@
|
||||
/**
|
||||
* Copyright (C) 2023-present MongoDB, Inc.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the Server Side Public License, version 1,
|
||||
* as published by MongoDB, Inc.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* Server Side Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the Server Side Public License
|
||||
* along with this program. If not, see
|
||||
* <http://www.mongodb.com/licensing/server-side-public-license>.
|
||||
*
|
||||
* As a special exception, the copyright holders give permission to link the
|
||||
* code of portions of this program with the OpenSSL library under certain
|
||||
* conditions as described in each individual source file and distribute
|
||||
* linked combinations including the program with the OpenSSL library. You
|
||||
* must comply with the Server Side Public License in all respects for
|
||||
* all of the code used other than as permitted herein. If you modify file(s)
|
||||
* with this exception, you may extend this exception to your version of the
|
||||
* file(s), but you are not obligated to do so. If you do not wish to do so,
|
||||
* delete this exception statement from your version. If you delete this
|
||||
* exception statement from all source files in the program, then also delete
|
||||
* it in the license file.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <clang-tidy/ClangTidy.h>
|
||||
#include <clang-tidy/ClangTidyCheck.h>
|
||||
|
||||
namespace mongo::tidy {
|
||||
|
||||
/**
|
||||
* check for usage of std::atomic
|
||||
* Overrides the default registerMatchers function to add matcher to match the
|
||||
* usage of std::atomic. overrides the default check function to
|
||||
* flag the uses of std::atomic to enforce our commitment to boost::atomic
|
||||
*/
|
||||
class MongoStdAtomicCheck : public clang::tidy::ClangTidyCheck {
|
||||
|
||||
public:
|
||||
MongoStdAtomicCheck(clang::StringRef Name, clang::tidy::ClangTidyContext* Context);
|
||||
void registerMatchers(clang::ast_matchers::MatchFinder* Finder) override;
|
||||
void check(const clang::ast_matchers::MatchFinder::MatchResult& Result) override;
|
||||
};
|
||||
|
||||
} // namespace mongo::tidy
|
||||
@ -28,6 +28,8 @@
|
||||
*/
|
||||
|
||||
#include "MongoStdOptionalCheck.h"
|
||||
#include "MongoTidyUtils.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
namespace mongo::tidy {
|
||||
@ -38,42 +40,6 @@ using namespace clang::ast_matchers;
|
||||
MongoStdOptionalCheck::MongoStdOptionalCheck(StringRef Name, clang::tidy::ClangTidyContext* Context)
|
||||
: ClangTidyCheck(Name, Context) {}
|
||||
|
||||
/**
|
||||
Matches declarations whose declaration context is the C++ standard library
|
||||
namespace std.
|
||||
|
||||
Note that inline namespaces are silently ignored during the lookup since
|
||||
both libstdc++ and libc++ are known to use them for versioning purposes.
|
||||
|
||||
Given:
|
||||
\code
|
||||
namespace ns {
|
||||
struct my_type {};
|
||||
using namespace std;
|
||||
}
|
||||
|
||||
using std::optional;
|
||||
using ns:my_type;
|
||||
using ns::optional;
|
||||
\code
|
||||
|
||||
usingDecl(hasAnyUsingShadowDecl(hasTargetDecl(isFromStdNamespace())))
|
||||
matches "using std::optional" and "using ns::optional".
|
||||
*/
|
||||
AST_MATCHER(Decl, isFromStdNamespace) {
|
||||
const DeclContext* D = Node.getDeclContext();
|
||||
|
||||
while (D->isInlineNamespace())
|
||||
D = D->getParent();
|
||||
|
||||
if (!D->isNamespace() || !D->getParent()->isTranslationUnit())
|
||||
return false;
|
||||
|
||||
const IdentifierInfo* Info = cast<NamespaceDecl>(D)->getIdentifier();
|
||||
|
||||
return (Info && Info->isStr("std"));
|
||||
}
|
||||
|
||||
void MongoStdOptionalCheck::registerMatchers(ast_matchers::MatchFinder* Finder) {
|
||||
|
||||
// match using std::optional;
|
||||
|
||||
@ -27,8 +27,11 @@
|
||||
* it in the license file.
|
||||
*/
|
||||
|
||||
#include "MongoAssertCheck.h"
|
||||
#include "MongoCctypeCheck.h"
|
||||
#include "MongoHeaderBracketCheck.h"
|
||||
#include "MongoMutexCheck.h"
|
||||
#include "MongoStdAtomicCheck.h"
|
||||
#include "MongoStdOptionalCheck.h"
|
||||
#include "MongoTraceCheck.h"
|
||||
#include "MongoUninterruptibleLockGuardCheck.h"
|
||||
@ -52,6 +55,9 @@ public:
|
||||
CheckFactories.registerCheck<MongoStdOptionalCheck>("mongo-std-optional-check");
|
||||
CheckFactories.registerCheck<MongoVolatileCheck>("mongo-volatile-check");
|
||||
CheckFactories.registerCheck<MongoTraceCheck>("mongo-trace-check");
|
||||
CheckFactories.registerCheck<MongoStdAtomicCheck>("mongo-std-atomic-check");
|
||||
CheckFactories.registerCheck<MongoMutexCheck>("mongo-mutex-check");
|
||||
CheckFactories.registerCheck<MongoAssertCheck>("mongo-assert-check");
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
80
src/mongo/tools/mongo_tidy_checks/MongoTidyUtils.h
Normal file
80
src/mongo/tools/mongo_tidy_checks/MongoTidyUtils.h
Normal file
@ -0,0 +1,80 @@
|
||||
/**
|
||||
* Copyright (C) 2023-present MongoDB, Inc.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the Server Side Public License, version 1,
|
||||
* as published by MongoDB, Inc.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* Server Side Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the Server Side Public License
|
||||
* along with this program. If not, see
|
||||
* <http://www.mongodb.com/licensing/server-side-public-license>.
|
||||
*
|
||||
* As a special exception, the copyright holders give permission to link the
|
||||
* code of portions of this program with the OpenSSL library under certain
|
||||
* conditions as described in each individual source file and distribute
|
||||
* linked combinations including the program with the OpenSSL library. You
|
||||
* must comply with the Server Side Public License in all respects for
|
||||
* all of the code used other than as permitted herein. If you modify file(s)
|
||||
* with this exception, you may extend this exception to your version of the
|
||||
* file(s), but you are not obligated to do so. If you do not wish to do so,
|
||||
* delete this exception statement from your version. If you delete this
|
||||
* exception statement from all source files in the program, then also delete
|
||||
* it in the license file.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <clang/AST/AST.h>
|
||||
#include <clang/ASTMatchers/ASTMatchers.h>
|
||||
#include <clang/Basic/IdentifierTable.h>
|
||||
#include <llvm/Support/Casting.h>
|
||||
|
||||
namespace mongo {
|
||||
|
||||
// Matches declarations whose declaration context is the C++ standard library
|
||||
// namespace std.
|
||||
|
||||
// Note that inline namespaces are silently ignored during the lookup since
|
||||
// both libstdc++ and libc++ are known to use them for versioning purposes.
|
||||
|
||||
// Given:
|
||||
// \code
|
||||
// namespace ns {
|
||||
// struct my_type {};
|
||||
// using namespace std;
|
||||
// }
|
||||
|
||||
// using std::xxxxxx;
|
||||
// using ns:my_type;
|
||||
// using ns::xxxxxx;
|
||||
// \code
|
||||
|
||||
// usingDecl(hasAnyUsingShadowDecl(hasTargetDecl(isFromStdNamespace())))
|
||||
// matches "using std::xxxxxx" and "using ns::xxxxxx".
|
||||
// */
|
||||
|
||||
AST_MATCHER(clang::Decl, isFromStdNamespace) {
|
||||
|
||||
// Get the declaration context of the current node.
|
||||
const clang::DeclContext* D = Node.getDeclContext();
|
||||
|
||||
// Iterate through any inline namespaces to get the top-level namespace context.
|
||||
while (D->isInlineNamespace())
|
||||
D = D->getParent();
|
||||
|
||||
// Check if the top-level context is a namespace and is the translation unit.
|
||||
if (!D->isNamespace() || !D->getParent()->isTranslationUnit())
|
||||
return false;
|
||||
|
||||
// Retrieve the identifier information of the namespace declaration.
|
||||
const clang::IdentifierInfo* Info = llvm::cast<clang::NamespaceDecl>(D)->getIdentifier();
|
||||
|
||||
// Check if the identifier information exists and matches the string "std".
|
||||
return (Info && Info->isStr("std"));
|
||||
}
|
||||
|
||||
} // namespace mongo
|
||||
@ -126,8 +126,11 @@ mongo_custom_check = env.SharedLibrary(
|
||||
"MongoCctypeCheck.cpp",
|
||||
"MongoStdOptionalCheck.cpp",
|
||||
"MongoVolatileCheck.cpp",
|
||||
"MongoStdAtomicCheck.cpp",
|
||||
"MongoTidyModule.cpp",
|
||||
"MongoTraceCheck.cpp",
|
||||
"MongoMutexCheck.cpp",
|
||||
"MongoAssertCheck.cpp",
|
||||
],
|
||||
LIBDEPS_NO_INHERIT=[
|
||||
'$BUILD_DIR/third_party/shim_allocator',
|
||||
|
||||
@ -181,7 +181,52 @@ class MongoTidyTests(unittest.TestCase):
|
||||
]
|
||||
|
||||
self.run_clang_tidy()
|
||||
|
||||
def test_MongoStdAtomicCheck(self):
|
||||
|
||||
self.write_config(
|
||||
textwrap.dedent("""\
|
||||
Checks: '-*,mongo-std-atomic-check'
|
||||
WarningsAsErrors: '*'
|
||||
"""))
|
||||
|
||||
self.expected_output = [
|
||||
"Illegal use of prohibited std::atomic<T>, use AtomicWord<T> or other types from \"mongo/platform/atomic_word.h\" [mongo-std-atomic-check,-warnings-as-errors]\nstd::atomic<int> atomic_var;",
|
||||
"Illegal use of prohibited std::atomic<T>, use AtomicWord<T> or other types from \"mongo/platform/atomic_word.h\" [mongo-std-atomic-check,-warnings-as-errors]\n std::atomic<int> field_decl;",
|
||||
]
|
||||
|
||||
self.run_clang_tidy()
|
||||
|
||||
def test_MongoMutexCheck(self):
|
||||
|
||||
self.write_config(
|
||||
textwrap.dedent("""\
|
||||
Checks: '-*,mongo-mutex-check,mongo-std-atomic-check'
|
||||
WarningsAsErrors: '*'
|
||||
"""))
|
||||
|
||||
self.expected_output = [
|
||||
"Illegal use of prohibited stdx::mutex, use mongo::Mutex from mongo/platform/mutex.h instead. [mongo-mutex-check,-warnings-as-errors]\nstdx::mutex stdxmutex_vardecl;",
|
||||
"Illegal use of prohibited stdx::mutex, use mongo::Mutex from mongo/platform/mutex.h instead. [mongo-mutex-check,-warnings-as-errors]\nstd::mutex stdmutex_vardecl;",
|
||||
"Illegal use of prohibited stdx::mutex, use mongo::Mutex from mongo/platform/mutex.h instead. [mongo-mutex-check,-warnings-as-errors]\n std::mutex stdmutex_fileddecl;",
|
||||
"Illegal use of prohibited stdx::mutex, use mongo::Mutex from mongo/platform/mutex.h instead. [mongo-mutex-check,-warnings-as-errors]\n stdx::mutex stdxmutex_fileddecl;",
|
||||
]
|
||||
|
||||
self.run_clang_tidy()
|
||||
|
||||
def test_MongoAssertCheck(self):
|
||||
|
||||
self.write_config(
|
||||
textwrap.dedent("""\
|
||||
Checks: '-*,mongo-assert-check'
|
||||
WarningsAsErrors: '*'
|
||||
"""))
|
||||
|
||||
self.expected_output = [
|
||||
"error: Illegal use of the bare assert function, use a function from assert_util.h instead",
|
||||
]
|
||||
|
||||
self.run_clang_tidy()
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
|
||||
@ -31,6 +31,9 @@ if env.GetOption('ninja') == 'disabled':
|
||||
'test_MongoCctypeCheck.cpp',
|
||||
'test_MongoStdOptionalCheck.cpp',
|
||||
'test_MongoTraceCheck.cpp',
|
||||
'test_MongoStdAtomicCheck.cpp',
|
||||
'test_MongoMutexCheck.cpp',
|
||||
'test_MongoAssertCheck.cpp',
|
||||
]
|
||||
|
||||
# So that we can do fast runs, we will generate a separate compilation database file for each
|
||||
|
||||
@ -0,0 +1,9 @@
|
||||
#include <cassert>
|
||||
namespace mongo {
|
||||
|
||||
void testAssertFunction() {
|
||||
int x = 10;
|
||||
assert(x > 0 && "x should be postive");
|
||||
}
|
||||
|
||||
} // namespace mongo
|
||||
@ -0,0 +1,18 @@
|
||||
#include <mutex>
|
||||
namespace mongo {
|
||||
|
||||
namespace stdx {
|
||||
using ::std::mutex;
|
||||
} // namespace stdx
|
||||
|
||||
// var Decl
|
||||
stdx::mutex stdxmutex_vardecl;
|
||||
std::mutex stdmutex_vardecl;
|
||||
|
||||
// field decl
|
||||
struct structName {
|
||||
std::mutex stdmutex_fileddecl;
|
||||
stdx::mutex stdxmutex_fileddecl;
|
||||
};
|
||||
|
||||
} // namespace mongo
|
||||
@ -0,0 +1,13 @@
|
||||
#include <atomic>
|
||||
|
||||
namespace mongo {
|
||||
|
||||
// Variable Decl
|
||||
std::atomic<int> atomic_var;
|
||||
|
||||
// Field Decl
|
||||
struct structName {
|
||||
std::atomic<int> field_decl;
|
||||
};
|
||||
|
||||
} // namespace mongo
|
||||
@ -183,8 +183,8 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
value_type _value; ///< guarded by _mutex
|
||||
mutable mutex_type _mutex = mutex_policy_type::construct();
|
||||
value_type _value; ///< guarded by _mutex
|
||||
mutable mutex_type _mutex = mutex_policy_type::construct(); // NOLINT(mongo-mutex-check)
|
||||
};
|
||||
|
||||
} // namespace mongo
|
||||
|
||||
Loading…
Reference in New Issue
Block a user