Adding a checker (cert-dcl50-cpp) that detects the definition of a C-style variadic function in C++ code. Corresponds to the CERT C++ secure coding rule: https://www.securecoding.cert.org/confluence/display/cplusplus/DCL50-CPP.+Do+not+define+a+C-style+variadic+function

llvm-svn: 249343
This commit is contained in:
Aaron Ballman 2015-10-05 20:08:59 +00:00
parent 42fd9efa38
commit 46bc30472b
7 changed files with 108 additions and 0 deletions

View File

@ -15,6 +15,7 @@
#include "../misc/NewDeleteOverloadsCheck.h"
#include "../misc/NonCopyableObjects.h"
#include "../misc/StaticAssertCheck.h"
#include "VariadicFunctionDefCheck.h"
namespace clang {
namespace tidy {
@ -25,6 +26,8 @@ public:
void addCheckFactories(ClangTidyCheckFactories &CheckFactories) override {
// C++ checkers
// DCL
CheckFactories.registerCheck<VariadicFunctionDefCheck>(
"cert-dcl50-cpp");
CheckFactories.registerCheck<misc::NewDeleteOverloadsCheck>(
"cert-dcl54-cpp");
CheckFactories.registerCheck<google::build::UnnamedNamespaceInHeaderCheck>(

View File

@ -2,6 +2,7 @@ set(LLVM_LINK_COMPONENTS support)
add_clang_library(clangTidyCERTModule
CERTTidyModule.cpp
VariadicFunctionDefCheck.cpp
LINK_LIBS
clangAST

View File

@ -0,0 +1,38 @@
//===--- VariadicfunctiondefCheck.cpp - clang-tidy-------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "VariadicFunctionDefCheck.h"
#include "clang/AST/ASTContext.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
using namespace clang::ast_matchers;
namespace clang {
namespace tidy {
void VariadicFunctionDefCheck::registerMatchers(MatchFinder *Finder) {
if (!getLangOpts().CPlusPlus)
return;
// We only care about function *definitions* that are variadic.
Finder->addMatcher(functionDecl(isDefinition(), isVariadic()).bind("func"),
this);
}
void VariadicFunctionDefCheck::check(const MatchFinder::MatchResult &Result) {
const auto *FD = Result.Nodes.getNodeAs<FunctionDecl>("func");
diag(FD->getLocation(),
"do not define a C-style variadic function; consider using a function "
"parameter pack or currying instead");
}
} // namespace tidy
} // namespace clang

View File

@ -0,0 +1,34 @@
//===--- VariadicFunctionDefCheck.h - clang-tidy-----------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CERT_VARIADICFUNCTIONDEF_H
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CERT_VARIADICFUNCTIONDEF_H
#include "../ClangTidy.h"
namespace clang {
namespace tidy {
/// Guards against any C-style variadic function definitions (not declarations).
///
/// For the user-facing documentation see:
/// http://clang.llvm.org/extra/clang-tidy/checks/cert-variadic-function-def.html
class VariadicFunctionDefCheck : public ClangTidyCheck {
public:
VariadicFunctionDefCheck(StringRef Name, ClangTidyContext *Context)
: ClangTidyCheck(Name, Context) {}
void registerMatchers(ast_matchers::MatchFinder *Finder) override;
void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
};
} // namespace tidy
} // namespace clang
#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CERT_VARIADICFUNCTIONDEF_H

View File

@ -0,0 +1,13 @@
cert-dcl50-cpp
========================
A variadic function using an ellipsis has no mechanisms to check the type safety
of arguments being passed to the function or to check that the number of
arguments being passed matches the semantics of the function definition.
Consequently, a runtime call to a C-style variadic function that passes
inappropriate arguments yields undefined behavior. Such undefined behavior could
be exploited to run arbitrary code.
This check corresponds to the CERT C++ Coding Standard rule
`DCL50-CPP. Do not define a C-style variadic function
<https://www.securecoding.cert.org/confluence/display/cplusplus/DCL50-CPP.+Do+not+define+a+C-style+variadic+function>`_.

View File

@ -2,6 +2,7 @@ List of clang-tidy Checks
=========================
.. toctree::
cert-variadic-function-def
google-build-explicit-make-pair
google-build-namespaces
google-build-using-namespace

View File

@ -0,0 +1,18 @@
// RUN: %python %S/check_clang_tidy.py %s cert-dcl50-cpp %t
// Variadic function definitions are diagnosed.
void f1(int, ...) {}
// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: do not define a C-style variadic function; consider using a function parameter pack or currying instead [cert-dcl50-cpp]
// Variadic function *declarations* are not diagnosed.
void f2(int, ...); // ok
// Function parameter packs are good, however.
template <typename Arg, typename... Ts>
void f3(Arg F, Ts... Rest) {}
struct S {
void f(int, ...); // ok
void f1(int, ...) {}
// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: do not define a C-style variadic function; consider using a function parameter pack or currying instead
};