clang-tools 6.0.0

UndefinedMemoryManipulationCheck.cpp
Go to the documentation of this file.
1 //===--- UndefinedMemoryManipulationCheck.cpp - clang-tidy-----------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include "UndefinedMemoryManipulationCheck.h"
11 #include "clang/AST/ASTContext.h"
12 #include "clang/ASTMatchers/ASTMatchFinder.h"
13
14 using namespace clang::ast_matchers;
15
16 namespace clang {
17 namespace tidy {
18 namespace bugprone {
19
20 namespace {
21 AST_MATCHER(CXXRecordDecl, isNotTriviallyCopyable) {
22 // For incomplete types, assume they are TriviallyCopyable.
23 return Node.hasDefinition() ? !Node.isTriviallyCopyable() : false;
24 }
25 } // namespace
26
27 void UndefinedMemoryManipulationCheck::registerMatchers(MatchFinder *Finder) {
28 const auto NotTriviallyCopyableObject =
29 hasType(ast_matchers::hasCanonicalType(
30 pointsTo(cxxRecordDecl(isNotTriviallyCopyable()))));
31
32 // Check whether destination object is not TriviallyCopyable.
33 // Applicable to all three memory manipulation functions.
34 Finder->addMatcher(callExpr(callee(functionDecl(hasAnyName(
35 "::memset", "::memcpy", "::memmove"))),
36 hasArgument(0, NotTriviallyCopyableObject))
37 .bind("dest"),
38 this);
39
40 // Check whether source object is not TriviallyCopyable.
41 // Only applicable to memcpy() and memmove().
42 Finder->addMatcher(
43 callExpr(callee(functionDecl(hasAnyName("::memcpy", "::memmove"))),
44 hasArgument(1, NotTriviallyCopyableObject))
45 .bind("src"),
46 this);
47 }
48
49 void UndefinedMemoryManipulationCheck::check(
50 const MatchFinder::MatchResult &Result) {
51 if (const auto *Call = Result.Nodes.getNodeAs<CallExpr>("dest")) {
52 QualType DestType = Call->getArg(0)->IgnoreImplicit()->getType();
53 if (!DestType->getPointeeType().isNull())
54 DestType = DestType->getPointeeType();
55 diag(Call->getLocStart(), "undefined behavior, destination object type %0 "
56 "is not TriviallyCopyable")
57 << DestType;
58 }
59 if (const auto *Call = Result.Nodes.getNodeAs<CallExpr>("src")) {
60 QualType SourceType = Call->getArg(1)->IgnoreImplicit()->getType();
61 if (!SourceType->getPointeeType().isNull())
62 SourceType = SourceType->getPointeeType();
63 diag(Call->getLocStart(),
64 "undefined behavior, source object type %0 is not TriviallyCopyable")
65 << SourceType;
66 }
67 }
68
69 } // namespace bugprone
70 } // namespace tidy
71 } // namespace clang
clang::ast_matchers
Definition: ClangTidyDiagnosticConsumer.h:27
UndefinedMemoryManipulationCheck.h
clang
Definition: AndroidTidyModule.cpp:28
clang::ast_matchers::AST_MATCHER
AST_MATCHER(VarDecl, isAsm)
Definition: NoAssemblerCheck.cpp:18