Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/tools/clang/lib/StaticAnalyzer/Core/DynamicTypeMap.cpp
Line
Count
Source (jump to first uncovered line)
1
//===- DynamicTypeMap.cpp - Dynamic Type Info related APIs ----------------===//
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 APIs that track and query dynamic type information. This
10
//  information can be used to devirtualize calls during the symbolic execution
11
//  or do type checking.
12
//
13
//===----------------------------------------------------------------------===//
14
15
#include "clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeMap.h"
16
#include "clang/Basic/JsonSupport.h"
17
#include "clang/Basic/LLVM.h"
18
#include "clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
19
#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
20
#include "clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h"
21
#include "llvm/Support/Casting.h"
22
#include "llvm/Support/raw_ostream.h"
23
#include <cassert>
24
25
namespace clang {
26
namespace ento {
27
28
DynamicTypeInfo getDynamicTypeInfo(ProgramStateRef State,
29
6.76k
                                   const MemRegion *Reg) {
30
6.76k
  Reg = Reg->StripCasts();
31
6.76k
32
6.76k
  // Look up the dynamic type in the GDM.
33
6.76k
  const DynamicTypeInfo *GDMType = State->get<DynamicTypeMap>(Reg);
34
6.76k
  if (GDMType)
35
2.54k
    return *GDMType;
36
4.22k
37
4.22k
  // Otherwise, fall back to what we know about the region.
38
4.22k
  if (const auto *TR = dyn_cast<TypedRegion>(Reg))
39
329
    return DynamicTypeInfo(TR->getLocationType(), /*CanBeSub=*/false);
40
3.89k
41
3.89k
  if (const auto *SR = dyn_cast<SymbolicRegion>(Reg)) {
42
3.89k
    SymbolRef Sym = SR->getSymbol();
43
3.89k
    return DynamicTypeInfo(Sym->getType());
44
3.89k
  }
45
1
46
1
  return {};
47
1
}
48
49
ProgramStateRef setDynamicTypeInfo(ProgramStateRef State, const MemRegion *Reg,
50
3.84k
                                   DynamicTypeInfo NewTy) {
51
3.84k
  Reg = Reg->StripCasts();
52
3.84k
  ProgramStateRef NewState = State->set<DynamicTypeMap>(Reg, NewTy);
53
3.84k
  assert(NewState);
54
3.84k
  return NewState;
55
3.84k
}
56
57
void printDynamicTypeInfoJson(raw_ostream &Out, ProgramStateRef State,
58
4
                              const char *NL, unsigned int Space, bool IsDot) {
59
4
  Indent(Out, Space, IsDot) << "\"dynamic_types\": ";
60
4
61
4
  const DynamicTypeMapTy &DTM = State->get<DynamicTypeMap>();
62
4
  if (DTM.isEmpty()) {
63
4
    Out << "null," << NL;
64
4
    return;
65
4
  }
66
0
67
0
  ++Space;
68
0
  Out << '[' << NL;
69
0
  for (DynamicTypeMapTy::iterator I = DTM.begin(); I != DTM.end(); ++I) {
70
0
    const MemRegion *MR = I->first;
71
0
    const DynamicTypeInfo &DTI = I->second;
72
0
    Out << "{ \"region\": \"" << MR << "\", \"dyn_type\": ";
73
0
    if (DTI.isValid()) {
74
0
      Out << '\"' << DTI.getType()->getPointeeType().getAsString()
75
0
          << "\", \"sub_classable\": "
76
0
          << (DTI.canBeASubClass() ? "true" : "false");
77
0
    } else {
78
0
      Out << "null"; // Invalid type info
79
0
    }
80
0
    Out << "}";
81
0
82
0
    if (std::next(I) != DTM.end())
83
0
      Out << ',';
84
0
    Out << NL;
85
0
  }
86
0
87
0
  --Space;
88
0
  Indent(Out, Space, IsDot) << "]," << NL;
89
0
}
90
91
334k
void *ProgramStateTrait<DynamicTypeMap>::GDMIndex() {
92
334k
  static int index = 0;
93
334k
  return &index;
94
334k
}
95
96
} // namespace ento
97
} // namespace clang