[clang-tools-extra] r296734 - [clang-tidy] Function names configurable for cppcoreguidelines-nomalloc - checker
Alexander Kornienko via cfe-commits
cfe-commits at lists.llvm.org
Thu Mar 2 00:28:56 PST 2017
Author: alexfh
Date: Thu Mar 2 02:28:55 2017
New Revision: 296734
URL: http://llvm.org/viewvc/llvm-project?rev=296734&view=rev
Log:
[clang-tidy] Function names configurable for cppcoreguidelines-nomalloc - checker
Summary:
Hello everybody,
this is an incremental patch for the NoMalloc-Checker I wrote. It allows to configure the memory-management functions, that are checked,
This might be helpful for a code base with custom functions in use, or non-standard functionality, like posix_memalign.
Reviewers: aaron.ballman, hokein, alexfh
Reviewed By: aaron.ballman, alexfh
Subscribers: sbenza, nemanjai, JDevlieghere
Tags: #clang-tools-extra
Patch by Jonas Toth!
Differential Revision: https://reviews.llvm.org/D28239
Added:
clang-tools-extra/trunk/test/clang-tidy/cppcoreguidelines-no-malloc-custom.cpp
clang-tools-extra/trunk/test/clang-tidy/cppcoreguidelines-no-malloc-no-functions.cpp
Modified:
clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/NoMallocCheck.cpp
clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/NoMallocCheck.h
clang-tools-extra/trunk/docs/ReleaseNotes.rst
clang-tools-extra/trunk/docs/clang-tidy/checks/cppcoreguidelines-no-malloc.rst
Modified: clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/NoMallocCheck.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/NoMallocCheck.cpp?rev=296734&r1=296733&r2=296734&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/NoMallocCheck.cpp (original)
+++ clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/NoMallocCheck.cpp Thu Mar 2 02:28:55 2017
@@ -8,43 +8,63 @@
//===----------------------------------------------------------------------===//
#include "NoMallocCheck.h"
+#include "../utils/Matchers.h"
+#include "../utils/OptionsUtils.h"
#include "clang/AST/ASTContext.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
-#include <iostream>
+#include <algorithm>
#include <string>
+#include <vector>
using namespace clang::ast_matchers;
+using namespace clang::ast_matchers::internal;
namespace clang {
namespace tidy {
namespace cppcoreguidelines {
+namespace {
+Matcher<FunctionDecl> hasAnyListedName(const std::string &FunctionNames) {
+ const std::vector<std::string> NameList =
+ utils::options::parseStringList(FunctionNames);
+ return hasAnyName(std::vector<StringRef>(NameList.begin(), NameList.end()));
+}
+}
+
+void NoMallocCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
+ Options.store(Opts, "Allocations", AllocList);
+ Options.store(Opts, "Reallocations", ReallocList);
+ Options.store(Opts, "Deallocations", DeallocList);
+}
+
void NoMallocCheck::registerMatchers(MatchFinder *Finder) {
// C-style memory management is only problematic in C++.
if (!getLangOpts().CPlusPlus)
return;
// Registering malloc, will suggest RAII.
- Finder->addMatcher(
- callExpr(callee(functionDecl(hasAnyName("::malloc", "::calloc"))))
- .bind("aquisition"),
- this);
+ Finder->addMatcher(callExpr(callee(functionDecl(hasAnyListedName(AllocList))))
+ .bind("allocation"),
+ this);
// Registering realloc calls, suggest std::vector or std::string.
Finder->addMatcher(
- callExpr(callee(functionDecl(hasName("::realloc")))).bind("realloc"),
+ callExpr(callee(functionDecl(hasAnyListedName(ReallocList))))
+ .bind("realloc"),
this);
// Registering free calls, will suggest RAII instead.
Finder->addMatcher(
- callExpr(callee(functionDecl(hasName("::free")))).bind("free"), this);
+ callExpr(callee(functionDecl(hasAnyListedName(DeallocList))))
+ .bind("free"),
+ this);
}
void NoMallocCheck::check(const MatchFinder::MatchResult &Result) {
const CallExpr *Call = nullptr;
StringRef Recommendation;
- if ((Call = Result.Nodes.getNodeAs<CallExpr>("aquisition")))
+ if ((Call = Result.Nodes.getNodeAs<CallExpr>("allocation")))
Recommendation = "consider a container or a smart pointer";
else if ((Call = Result.Nodes.getNodeAs<CallExpr>("realloc")))
Recommendation = "consider std::vector or std::string";
Modified: clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/NoMallocCheck.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/NoMallocCheck.h?rev=296734&r1=296733&r2=296734&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/NoMallocCheck.h (original)
+++ clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/NoMallocCheck.h Thu Mar 2 02:28:55 2017
@@ -27,14 +27,32 @@ namespace cppcoreguidelines {
/// http://clang.llvm.org/extra/clang-tidy/checks/cppcoreguidelines-no-malloc.html
class NoMallocCheck : public ClangTidyCheck {
public:
+ /// Construct Checker and read in configuration for function names.
NoMallocCheck(StringRef Name, ClangTidyContext *Context)
- : ClangTidyCheck(Name, Context) {}
+ : ClangTidyCheck(Name, Context),
+ AllocList(Options.get("Allocations", "::malloc;::calloc")),
+ ReallocList(Options.get("Reallocations", "::realloc")),
+ DeallocList(Options.get("Deallocations", "::free")) {}
+
+ /// Make configuration of checker discoverable.
+ void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
/// Registering for malloc, calloc, realloc and free calls.
void registerMatchers(ast_matchers::MatchFinder *Finder) override;
/// Checks matched function calls and gives suggestion to modernize the code.
void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+
+private:
+ /// Semicolon-seperated list of fully qualified names of memory allocation
+ /// functions the check warns about. Defaults to `::malloc;::calloc`.
+ const std::string AllocList;
+ /// Semicolon-seperated list of fully qualified names of memory reallocation
+ /// functions the check warns about. Defaults to `::realloc`.
+ const std::string ReallocList;
+ /// Semicolon-seperated list of fully qualified names of memory deallocation
+ /// functions the check warns about. Defaults to `::free`.
+ const std::string DeallocList;
};
} // namespace cppcoreguidelines
Modified: clang-tools-extra/trunk/docs/ReleaseNotes.rst
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/docs/ReleaseNotes.rst?rev=296734&r1=296733&r2=296734&view=diff
==============================================================================
--- clang-tools-extra/trunk/docs/ReleaseNotes.rst (original)
+++ clang-tools-extra/trunk/docs/ReleaseNotes.rst Thu Mar 2 02:28:55 2017
@@ -62,6 +62,11 @@ Improvements to clang-tidy
Finds modification of the ``std`` or ``posix`` namespace.
+- Improved `cppcoreguidelines-no-malloc
+ <http://clang.llvm.org/extra/clang-tidy/checks/cppcoreguidelines-no-malloc.html>`_ check
+
+ Allow custom memory management functions to be considered as well.
+
- New `readability-misleading-indentation
<http://clang.llvm.org/extra/clang-tidy/checks/readability-misleading-indentation.html>`_ check
Modified: clang-tools-extra/trunk/docs/clang-tidy/checks/cppcoreguidelines-no-malloc.rst
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/docs/clang-tidy/checks/cppcoreguidelines-no-malloc.rst?rev=296734&r1=296733&r2=296734&view=diff
==============================================================================
--- clang-tools-extra/trunk/docs/clang-tidy/checks/cppcoreguidelines-no-malloc.rst (original)
+++ clang-tools-extra/trunk/docs/clang-tidy/checks/cppcoreguidelines-no-malloc.rst Thu Mar 2 02:28:55 2017
@@ -6,8 +6,9 @@ cppcoreguidelines-no-malloc
This check handles C-Style memory management using ``malloc()``, ``realloc()``,
``calloc()`` and ``free()``. It warns about its use and tries to suggest the use
of an appropriate RAII object.
-See `C++ Core Guidelines
-<https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#Rr-mallocfree>`.
+Furthermore, it can be configured to check against a user-specified list of functions
+that are used for memory management (e.g. ``posix_memalign()``).
+See `C++ Core Guidelines <https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#Rr-mallocfree>`_.
There is no attempt made to provide fix-it hints, since manual resource
management isn't easily transformed automatically into RAII.
@@ -25,3 +26,21 @@ management isn't easily transformed auto
// Rather use a smartpointer or stack variable.
struct some_struct* s = (struct some_struct*) malloc(sizeof(struct some_struct));
+Options
+-------
+
+.. option:: Allocations
+
+ Semicolon-separated list of fully qualified names of memory allocation functions.
+ Defaults to ``::malloc;::calloc``.
+
+.. option:: Deallocations
+
+ Semicolon-separated list of fully qualified names of memory allocation functions.
+ Defaults to ``::free``.
+
+.. option:: Reallocations
+
+ Semicolon-separated list of fully qualified names of memory allocation functions.
+ Defaults to ``::realloc``.
+
Added: clang-tools-extra/trunk/test/clang-tidy/cppcoreguidelines-no-malloc-custom.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/cppcoreguidelines-no-malloc-custom.cpp?rev=296734&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/cppcoreguidelines-no-malloc-custom.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/cppcoreguidelines-no-malloc-custom.cpp Thu Mar 2 02:28:55 2017
@@ -0,0 +1,59 @@
+// RUN: %check_clang_tidy %s cppcoreguidelines-no-malloc %t \
+// RUN: -config='{CheckOptions: \
+// RUN: [{key: cppcoreguidelines-no-malloc.Allocations, value: "::malloc;::align_malloc;::calloc"},\
+// RUN: {key: cppcoreguidelines-no-malloc.Reallocations, value: "::realloc;::align_realloc"},\
+// RUN: {key: cppcoreguidelines-no-malloc.Deallocations, value: "::free;::align_free"}]}' \
+// RUN: --
+
+using size_t = __SIZE_TYPE__;
+
+void *malloc(size_t size);
+void *align_malloc(size_t size, unsigned short aligmnent);
+void *calloc(size_t num, size_t size);
+void *realloc(void *ptr, size_t size);
+void *align_realloc(void *ptr, size_t size, unsigned short alignment);
+void free(void *ptr);
+void *align_free(void *ptr);
+
+void malloced_array() {
+ int *array0 = (int *)malloc(sizeof(int) * 20);
+ // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: do not manage memory manually; consider a container or a smart pointer [cppcoreguidelines-no-malloc]
+
+ int *zeroed = (int *)calloc(20, sizeof(int));
+ // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: do not manage memory manually; consider a container or a smart pointer [cppcoreguidelines-no-malloc]
+
+ int *aligned = (int *)align_malloc(20 * sizeof(int), 16);
+ // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: do not manage memory manually; consider a container or a smart pointer [cppcoreguidelines-no-malloc]
+
+ // reallocation memory, std::vector shall be used
+ char *realloced = (char *)realloc(array0, 50 * sizeof(int));
+ // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: do not manage memory manually; consider std::vector or std::string [cppcoreguidelines-no-malloc]
+
+ char *align_realloced = (char *)align_realloc(aligned, 50 * sizeof(int), 16);
+ // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: do not manage memory manually; consider std::vector or std::string [cppcoreguidelines-no-malloc]
+
+ // freeing memory the bad way
+ free(realloced);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not manage memory manually; use RAII [cppcoreguidelines-no-malloc]
+
+ align_free(align_realloced);
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not manage memory manually; use RAII [cppcoreguidelines-no-malloc]
+
+ // check if a call to malloc as function argument is found as well
+ free(malloc(20));
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not manage memory manually; use RAII [cppcoreguidelines-no-malloc]
+ // CHECK-MESSAGES: :[[@LINE-2]]:8: warning: do not manage memory manually; consider a container or a smart pointer [cppcoreguidelines-no-malloc]
+}
+
+/// newing an array is still not good, but not relevant to this checker
+void newed_array() {
+ int *new_array = new int[10]; // OK(1)
+}
+
+void arbitrary_call() {
+ // we dont want every function to raise the warning even if malloc is in the name
+ malloced_array(); // OK(2)
+
+ // completly unrelated function call to malloc
+ newed_array(); // OK(3)
+}
Added: clang-tools-extra/trunk/test/clang-tidy/cppcoreguidelines-no-malloc-no-functions.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/cppcoreguidelines-no-malloc-no-functions.cpp?rev=296734&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/cppcoreguidelines-no-malloc-no-functions.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/cppcoreguidelines-no-malloc-no-functions.cpp Thu Mar 2 02:28:55 2017
@@ -0,0 +1,17 @@
+// RUN: %check_clang_tidy %s cppcoreguidelines-no-malloc %t \
+// RUN: -config='{CheckOptions: \
+// RUN: [{key: cppcoreguidelines-no-malloc.Allocations, value: "::malloc"},\
+// RUN: {key: cppcoreguidelines-no-malloc.Reallocations, value: ""},\
+// RUN: {key: cppcoreguidelines-no-malloc.Deallocations, value: ""}]}' \
+// RUN: --
+
+// Just ensure, the check will not crash, when no functions shall be checked.
+
+using size_t = __SIZE_TYPE__;
+
+void *malloc(size_t size);
+
+void malloced_array() {
+ int *array0 = (int *)malloc(sizeof(int) * 20);
+ // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: do not manage memory manually; consider a container or a smart pointer [cppcoreguidelines-no-malloc]
+}
More information about the cfe-commits
mailing list