clang-tools  7.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 
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
AST_MATCHER(BinaryOperator, isAssignmentOperator)
Definition: Matchers.h:20
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//