Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/tools/clang/lib/StaticAnalyzer/Checkers/SmartPtrModeling.cpp
Line
Count
Source
1
// SmartPtrModeling.cpp - Model behavior of C++ smart pointers - C++ ------===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
//
9
// This file defines a checker that models various aspects of
10
// C++ smart pointer behavior.
11
//
12
//===----------------------------------------------------------------------===//
13
14
#include "Move.h"
15
16
#include "clang/AST/ExprCXX.h"
17
#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
18
#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
19
#include "clang/StaticAnalyzer/Core/Checker.h"
20
#include "clang/StaticAnalyzer/Core/CheckerManager.h"
21
#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
22
#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
23
24
using namespace clang;
25
using namespace ento;
26
27
namespace {
28
class SmartPtrModeling : public Checker<eval::Call> {
29
  bool isNullAfterMoveMethod(const CallEvent &Call) const;
30
31
public:
32
  bool evalCall(const CallEvent &Call, CheckerContext &C) const;
33
};
34
} // end of anonymous namespace
35
36
20.6k
bool SmartPtrModeling::isNullAfterMoveMethod(const CallEvent &Call) const {
37
20.6k
  // TODO: Update CallDescription to support anonymous calls?
38
20.6k
  // TODO: Handle other methods, such as .get() or .release().
39
20.6k
  // But once we do, we'd need a visitor to explain null dereferences
40
20.6k
  // that are found via such modeling.
41
20.6k
  const auto *CD = dyn_cast_or_null<CXXConversionDecl>(Call.getDecl());
42
20.6k
  return CD && 
CD->getConversionType()->isBooleanType()90
;
43
20.6k
}
44
45
bool SmartPtrModeling::evalCall(const CallEvent &Call,
46
20.6k
                                CheckerContext &C) const {
47
20.6k
  if (!isNullAfterMoveMethod(Call))
48
20.6k
    return false;
49
68
50
68
  ProgramStateRef State = C.getState();
51
68
  const MemRegion *ThisR =
52
68
      cast<CXXInstanceCall>(&Call)->getCXXThisVal().getAsRegion();
53
68
54
68
  if (!move::isMovedFrom(State, ThisR)) {
55
53
    // TODO: Model this case as well. At least, avoid invalidation of globals.
56
53
    return false;
57
53
  }
58
15
59
15
  // TODO: Add a note to bug reports describing this decision.
60
15
  C.addTransition(
61
15
      State->BindExpr(Call.getOriginExpr(), C.getLocationContext(),
62
15
                      C.getSValBuilder().makeZeroVal(Call.getResultType())));
63
15
  return true;
64
15
}
65
66
48
void ento::registerSmartPtrModeling(CheckerManager &Mgr) {
67
48
  Mgr.registerChecker<SmartPtrModeling>();
68
48
}
69
70
48
bool ento::shouldRegisterSmartPtrModeling(const LangOptions &LO) {
71
48
  return LO.CPlusPlus;
72
48
}