clang  6.0.0svn
CXXSelfAssignmentChecker.cpp
Go to the documentation of this file.
1 //=== CXXSelfAssignmentChecker.cpp -----------------------------*- C++ -*--===//
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 // This file defines CXXSelfAssignmentChecker, which tests all custom defined
11 // copy and move assignment operators for the case of self assignment, thus
12 // where the parameter refers to the same location where the this pointer
13 // points to. The checker itself does not do any checks at all, but it
14 // causes the analyzer to check every copy and move assignment operator twice:
15 // once for when 'this' aliases with the parameter and once for when it may not.
16 // It is the task of the other enabled checkers to find the bugs in these two
17 // different cases.
18 //
19 //===----------------------------------------------------------------------===//
20 
21 #include "ClangSACheckers.h"
24 
25 using namespace clang;
26 using namespace ento;
27 
28 namespace {
29 
30 class CXXSelfAssignmentChecker : public Checker<check::BeginFunction> {
31 public:
32  CXXSelfAssignmentChecker();
33  void checkBeginFunction(CheckerContext &C) const;
34 };
35 }
36 
37 CXXSelfAssignmentChecker::CXXSelfAssignmentChecker() {}
38 
39 void CXXSelfAssignmentChecker::checkBeginFunction(CheckerContext &C) const {
40  if (!C.inTopFrame())
41  return;
42  const auto *LCtx = C.getLocationContext();
43  const auto *MD = dyn_cast<CXXMethodDecl>(LCtx->getDecl());
44  if (!MD)
45  return;
46  if (!MD->isCopyAssignmentOperator() && !MD->isMoveAssignmentOperator())
47  return;
48  auto &State = C.getState();
49  auto &SVB = C.getSValBuilder();
50  auto ThisVal =
51  State->getSVal(SVB.getCXXThis(MD, LCtx->getCurrentStackFrame()));
52  auto Param = SVB.makeLoc(State->getRegion(MD->getParamDecl(0), LCtx));
53  auto ParamVal = State->getSVal(Param);
54  ProgramStateRef SelfAssignState = State->bindLoc(Param, ThisVal, LCtx);
55  C.addTransition(SelfAssignState);
56  ProgramStateRef NonSelfAssignState = State->bindLoc(Param, ParamVal, LCtx);
57  C.addTransition(NonSelfAssignState);
58 }
59 
60 void ento::registerCXXSelfAssignmentChecker(CheckerManager &Mgr) {
61  Mgr.registerChecker<CXXSelfAssignmentChecker>();
62 }
ExplodedNode * addTransition(ProgramStateRef State=nullptr, const ProgramPointTag *Tag=nullptr)
Generates a new transition in the program state graph (ExplodedGraph).
LineState State
CHECKER * registerChecker()
Used to register checkers.
Represents a static or instance method of a struct/union/class.
Definition: DeclCXX.h:1964
Dataflow Directional Tag Classes.
const ProgramStateRef & getState() const
SValBuilder & getSValBuilder()
bool inTopFrame() const
Return true if the current LocationContext has no caller context.
const LocationContext * getLocationContext() const