]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/clang/lib/StaticAnalyzer/Checkers/CXXSelfAssignmentChecker.cpp
Merge llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / clang / lib / StaticAnalyzer / Checkers / CXXSelfAssignmentChecker.cpp
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 "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
22 #include "clang/StaticAnalyzer/Core/Checker.h"
23 #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.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->getStackFrame()));
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 }