-
Notifications
You must be signed in to change notification settings - Fork 10.8k
/
DynamicTypeMap.cpp
74 lines (64 loc) · 2.29 KB
/
DynamicTypeMap.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
//==- DynamicTypeMap.cpp - Dynamic Type Info related APIs ----------*- C++ -*-//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines APIs that track and query dynamic type information. This
// information can be used to devirtualize calls during the symbolic execution
// or do type checking.
//
//===----------------------------------------------------------------------===//
#include "clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeMap.h"
namespace clang {
namespace ento {
DynamicTypeInfo getDynamicTypeInfo(ProgramStateRef State,
const MemRegion *Reg) {
Reg = Reg->StripCasts();
// Look up the dynamic type in the GDM.
const DynamicTypeInfo *GDMType = State->get<DynamicTypeMap>(Reg);
if (GDMType)
return *GDMType;
// Otherwise, fall back to what we know about the region.
if (const TypedRegion *TR = dyn_cast<TypedRegion>(Reg))
return DynamicTypeInfo(TR->getLocationType(), /*CanBeSubclass=*/false);
if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(Reg)) {
SymbolRef Sym = SR->getSymbol();
return DynamicTypeInfo(Sym->getType());
}
return DynamicTypeInfo();
}
ProgramStateRef setDynamicTypeInfo(ProgramStateRef State, const MemRegion *Reg,
DynamicTypeInfo NewTy) {
Reg = Reg->StripCasts();
ProgramStateRef NewState = State->set<DynamicTypeMap>(Reg, NewTy);
assert(NewState);
return NewState;
}
void printDynamicTypeInfo(ProgramStateRef State, raw_ostream &Out,
const char *NL, const char *Sep) {
bool First = true;
for (const auto &I : State->get<DynamicTypeMap>()) {
if (First) {
Out << NL << "Dynamic types of regions:" << NL;
First = false;
}
const MemRegion *MR = I.first;
const DynamicTypeInfo &DTI = I.second;
Out << MR << " : ";
if (DTI.isValid()) {
Out << DTI.getType()->getPointeeType().getAsString();
if (DTI.canBeASubClass()) {
Out << " (or its subclass)";
}
} else {
Out << "Invalid type info";
}
Out << NL;
}
}
} // namespace ento
} // namespace clang