SERVER-78007 Move rand check to clang-tidy

This commit is contained in:
Juan Gu 2023-06-14 23:31:44 +00:00 committed by Evergreen Agent
parent bc2e514fa3
commit 77727c372b
9 changed files with 134 additions and 9 deletions

View File

@ -43,6 +43,7 @@ Checks: '-*,
mongo-macro-definition-leaks-check,
mongo-mutex-check,
mongo-assert-check,
mongo-rand-check,
mongo-std-optional-check,
mongo-uninterruptible-lock-guard-check,
mongo-unstructured-log-check,

View File

@ -52,9 +52,7 @@ def _make_polyfill_regex():
_RE_LINT = re.compile("//.*NOLINT")
_RE_COMMENT_STRIP = re.compile("//.*")
_RE_PATTERN_MONGO_POLYFILL = _make_polyfill_regex()
_RE_RAND = re.compile(r'\b(srand\(|rand\(\))')
_RE_GENERIC_FCV_COMMENT = re.compile(r'\(Generic FCV reference\):')
GENERIC_FCV = [
@ -147,7 +145,6 @@ class Linter:
continue
self._check_for_mongo_polyfill(linenum)
self._check_for_rand(linenum)
self._check_for_c_stdlib_headers(linenum)
# Relax the rule of commenting generic FCV references for files directly related to FCV
@ -215,12 +212,6 @@ class Linter:
'Illegal use of banned name from std::/boost:: for "%s", use mongo::stdx:: variant instead'
% (match.group(0)))
def _check_for_rand(self, linenum):
line = self.clean_lines[linenum]
if _RE_RAND.search(line):
self._error(linenum, 'mongodb/rand',
'Use of rand or srand, use <random> or PseudoRandom instead.')
def _license_error(self, linenum, msg, category='legal/license'):
style_url = 'https://github.com/mongodb/mongo/wiki/Server-Code-Style'
self._error(linenum, category, '{} See {}'.format(msg, style_url))

View 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.
*/
#include "MongoRandCheck.h"
namespace mongo::tidy {
using namespace clang;
using namespace clang::ast_matchers;
MongoRandCheck::MongoRandCheck(StringRef Name, clang::tidy::ClangTidyContext* Context)
: ClangTidyCheck(Name, Context) {}
void MongoRandCheck::registerMatchers(ast_matchers::MatchFinder* Finder) {
// Matcher for srand and sand functions
Finder->addMatcher(
callExpr(callee(functionDecl(hasAnyName("::srand", "::rand")))).bind("callExpr"), this);
}
void MongoRandCheck::check(const ast_matchers::MatchFinder::MatchResult& Result) {
// Get the matched check
const auto* CallExpr = Result.Nodes.getNodeAs<clang::CallExpr>("callExpr");
if (CallExpr) {
diag(CallExpr->getBeginLoc(),
"Use of rand or srand, use <random> or PseudoRandom instead.");
}
}
} // namespace mongo::tidy

View 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 {
/**
* MongoRandCheck is a custom clang-tidy check for detecting
* the usage of 'rand' and 'srand' functions in the source code.
*
* It extends ClangTidyCheck and overrides the registerMatchers
* and check functions. The registerMatchers function adds matchers
* to identify the usage of 'rand' and 'srand',
* while the check function flags the matched occurrences.
*/
class MongoRandCheck : public clang::tidy::ClangTidyCheck {
public:
MongoRandCheck(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

View File

@ -37,6 +37,7 @@
#include "MongoHeaderBracketCheck.h"
#include "MongoMacroDefinitionLeaksCheck.h"
#include "MongoMutexCheck.h"
#include "MongoRandCheck.h"
#include "MongoStdAtomicCheck.h"
#include "MongoStdOptionalCheck.h"
#include "MongoTraceCheck.h"
@ -75,6 +76,7 @@ public:
"mongo-collection-sharding-runtime-check");
CheckFactories.registerCheck<MongoMacroDefinitionLeaksCheck>(
"mongo-macro-definition-leaks-check");
CheckFactories.registerCheck<MongoRandCheck>("mongo-rand-check");
}
};

View File

@ -138,6 +138,7 @@ mongo_custom_check = env.SharedLibrary(
"MongoUnstructuredLogCheck.cpp",
"MongoCollectionShardingRuntimeCheck.cpp",
"MongoMacroDefinitionLeaksCheck.cpp",
"MongoRandCheck.cpp",
],
LIBDEPS_NO_INHERIT=[
'$BUILD_DIR/third_party/shim_allocator',

View File

@ -338,6 +338,20 @@ class MongoTidyTests(unittest.TestCase):
self.run_clang_tidy()
def test_MongoRandCheck(self):
self.write_config(
textwrap.dedent("""\
Checks: '-*,mongo-rand-check'
WarningsAsErrors: '*'
"""))
self.expected_output =[
"error: Use of rand or srand, use <random> or PseudoRandom instead. [mongo-rand-check,-warnings-as-errors]\n srand(time(0));",
"error: Use of rand or srand, use <random> or PseudoRandom instead. [mongo-rand-check,-warnings-as-errors]\n int random_number = rand();",
]
self.run_clang_tidy()
if __name__ == '__main__':
parser = argparse.ArgumentParser()

View File

@ -41,6 +41,7 @@ if env.GetOption('ninja') == 'disabled':
'test_MongoUnstructuredLogCheck.cpp',
'test_MongoCollectionShardingRuntimeCheck.cpp',
'test_MongoMacroDefinitionLeaksCheck.cpp',
'test_MongoRandCheck.cpp',
]
# So that we can do fast runs, we will generate a separate compilation database file for each

View File

@ -0,0 +1,8 @@
#include <cstdlib>
#include <ctime>
namespace mongo {
void mongoRandCheck() {
srand(time(0));
int random_number = rand();
}
} // namespace mongo