[clang-tidy] Add bugprone-undefined-memory-manipulation check
Patch by: Reka Nikolett Kovacs
Differential Revision: https://reviews.llvm.org/D35051
llvm-svn: 308021
diff --git a/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp b/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp
index 65353a2..aa5f629 100644
--- a/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp
@@ -11,6 +11,7 @@
#include "../ClangTidyModule.h"
#include "../ClangTidyModuleRegistry.h"
#include "SuspiciousMemsetUsageCheck.h"
+#include "UndefinedMemoryManipulationCheck.h"
namespace clang {
namespace tidy {
@@ -21,6 +22,8 @@
void addCheckFactories(ClangTidyCheckFactories &CheckFactories) override {
CheckFactories.registerCheck<SuspiciousMemsetUsageCheck>(
"bugprone-suspicious-memset-usage");
+ CheckFactories.registerCheck<UndefinedMemoryManipulationCheck>(
+ "bugprone-undefined-memory-manipulation");
}
};
diff --git a/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt b/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt
index 1f0ec6e..9ec45c5 100644
--- a/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt
+++ b/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt
@@ -3,6 +3,7 @@
add_clang_library(clangTidyBugproneModule
BugproneTidyModule.cpp
SuspiciousMemsetUsageCheck.cpp
+ UndefinedMemoryManipulationCheck.cpp
LINK_LIBS
clangAnalysis
diff --git a/clang-tools-extra/clang-tidy/bugprone/UndefinedMemoryManipulationCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/UndefinedMemoryManipulationCheck.cpp
new file mode 100644
index 0000000..cbc1f34
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/bugprone/UndefinedMemoryManipulationCheck.cpp
@@ -0,0 +1,61 @@
+//===--- UndefinedMemoryManipulationCheck.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 "UndefinedMemoryManipulationCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace tidy {
+namespace bugprone {
+
+namespace {
+AST_MATCHER(CXXRecordDecl, isNotTriviallyCopyable) {
+ return !Node.isTriviallyCopyable();
+}
+} // namespace
+
+void UndefinedMemoryManipulationCheck::registerMatchers(MatchFinder *Finder) {
+ const auto NotTriviallyCopyableObject =
+ hasType(pointsTo(cxxRecordDecl(isNotTriviallyCopyable())));
+
+ // Check whether destination object is not TriviallyCopyable.
+ // Applicable to all three memory manipulation functions.
+ Finder->addMatcher(callExpr(callee(functionDecl(hasAnyName(
+ "::memset", "::memcpy", "::memmove"))),
+ hasArgument(0, NotTriviallyCopyableObject))
+ .bind("dest"),
+ this);
+
+ // Check whether source object is not TriviallyCopyable.
+ // Only applicable to memcpy() and memmove().
+ Finder->addMatcher(
+ callExpr(callee(functionDecl(hasAnyName("::memcpy", "::memmove"))),
+ hasArgument(1, NotTriviallyCopyableObject))
+ .bind("src"),
+ this);
+}
+
+void UndefinedMemoryManipulationCheck::check(
+ const MatchFinder::MatchResult &Result) {
+ if (const auto *Destination = Result.Nodes.getNodeAs<CallExpr>("dest")) {
+ diag(Destination->getLocStart(), "undefined behavior, destination "
+ "object is not TriviallyCopyable");
+ }
+ if (const auto *Source = Result.Nodes.getNodeAs<CallExpr>("src")) {
+ diag(Source->getLocStart(), "undefined behavior, source object is not "
+ "TriviallyCopyable");
+ }
+}
+
+} // namespace bugprone
+} // namespace tidy
+} // namespace clang
diff --git a/clang-tools-extra/clang-tidy/bugprone/UndefinedMemoryManipulationCheck.h b/clang-tools-extra/clang-tidy/bugprone/UndefinedMemoryManipulationCheck.h
new file mode 100644
index 0000000..64d6c56
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/bugprone/UndefinedMemoryManipulationCheck.h
@@ -0,0 +1,37 @@
+//===--- UndefinedMemoryManipulationCheck.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_BUGPRONE_UNDEFINED_MEMORY_MANIPULATION_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_UNDEFINED_MEMORY_MANIPULATION_H
+
+#include "../ClangTidy.h"
+
+namespace clang {
+namespace tidy {
+namespace bugprone {
+
+/// Finds calls of memory manipulation functions ``memset()``, ``memcpy()`` and
+/// ``memmove()`` on not TriviallyCopyable objects resulting in undefined
+/// behavior.
+///
+/// For the user-facing documentation see:
+/// http://clang.llvm.org/extra/clang-tidy/checks/bugprone-undefined-memory-manipulation.html
+class UndefinedMemoryManipulationCheck : public ClangTidyCheck {
+public:
+ UndefinedMemoryManipulationCheck(StringRef Name, ClangTidyContext *Context)
+ : ClangTidyCheck(Name, Context) {}
+ void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+ void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+};
+
+} // namespace bugprone
+} // namespace tidy
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_UNDEFINED_MEMORY_MANIPULATION_H