]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - lib/Checker/ValueManager.cpp
Update clang to r96341.
[FreeBSD/FreeBSD.git] / lib / Checker / ValueManager.cpp
1 //== ValueManager.cpp - Aggregate manager of symbols and SVals --*- 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 ValueManager, a class that manages symbolic values
11 //  and SVals created for use by GRExprEngine and related classes.  It
12 //  wraps and owns SymbolManager, MemRegionManager, and BasicValueFactory.
13 //
14 //===----------------------------------------------------------------------===//
15
16 #include "clang/Checker/PathSensitive/ValueManager.h"
17 #include "clang/Analysis/AnalysisContext.h"
18
19 using namespace clang;
20 using namespace llvm;
21
22 //===----------------------------------------------------------------------===//
23 // Utility methods for constructing SVals.
24 //===----------------------------------------------------------------------===//
25
26 DefinedOrUnknownSVal ValueManager::makeZeroVal(QualType T) {
27   if (Loc::IsLocType(T))
28     return makeNull();
29
30   if (T->isIntegerType())
31     return makeIntVal(0, T);
32
33   // FIXME: Handle floats.
34   // FIXME: Handle structs.
35   return UnknownVal();
36 }
37
38 //===----------------------------------------------------------------------===//
39 // Utility methods for constructing Non-Locs.
40 //===----------------------------------------------------------------------===//
41
42 NonLoc ValueManager::makeNonLoc(const SymExpr *lhs, BinaryOperator::Opcode op,
43                                 const APSInt& v, QualType T) {
44   // The Environment ensures we always get a persistent APSInt in
45   // BasicValueFactory, so we don't need to get the APSInt from
46   // BasicValueFactory again.
47   assert(!Loc::IsLocType(T));
48   return nonloc::SymExprVal(SymMgr.getSymIntExpr(lhs, op, v, T));
49 }
50
51 NonLoc ValueManager::makeNonLoc(const SymExpr *lhs, BinaryOperator::Opcode op,
52                                 const SymExpr *rhs, QualType T) {
53   assert(SymMgr.getType(lhs) == SymMgr.getType(rhs));
54   assert(!Loc::IsLocType(T));
55   return nonloc::SymExprVal(SymMgr.getSymSymExpr(lhs, op, rhs, T));
56 }
57
58
59 SVal ValueManager::convertToArrayIndex(SVal V) {
60   if (V.isUnknownOrUndef())
61     return V;
62
63   // Common case: we have an appropriately sized integer.
64   if (nonloc::ConcreteInt* CI = dyn_cast<nonloc::ConcreteInt>(&V)) {
65     const llvm::APSInt& I = CI->getValue();
66     if (I.getBitWidth() == ArrayIndexWidth && I.isSigned())
67       return V;
68   }
69
70   return SVator->EvalCastNL(cast<NonLoc>(V), ArrayIndexTy);
71 }
72
73 DefinedOrUnknownSVal ValueManager::getRegionValueSymbolVal(const MemRegion* R,
74                                                            QualType T) {
75
76   if (T.isNull()) {
77     const TypedRegion* TR = cast<TypedRegion>(R);
78     T = TR->getValueType(SymMgr.getContext());
79   }
80
81   if (!SymbolManager::canSymbolicate(T))
82     return UnknownVal();
83
84   SymbolRef sym = SymMgr.getRegionValueSymbol(R, T);
85
86   if (Loc::IsLocType(T))
87     return loc::MemRegionVal(MemMgr.getSymbolicRegion(sym));
88
89   return nonloc::SymbolVal(sym);
90 }
91
92 DefinedOrUnknownSVal ValueManager::getConjuredSymbolVal(const void *SymbolTag,
93                                                         const Expr *E,
94                                                         unsigned Count) {
95   QualType T = E->getType();
96
97   if (!SymbolManager::canSymbolicate(T))
98     return UnknownVal();
99
100   SymbolRef sym = SymMgr.getConjuredSymbol(E, Count, SymbolTag);
101
102   if (Loc::IsLocType(T))
103     return loc::MemRegionVal(MemMgr.getSymbolicRegion(sym));
104
105   return nonloc::SymbolVal(sym);
106 }
107
108 DefinedOrUnknownSVal ValueManager::getConjuredSymbolVal(const void *SymbolTag,
109                                                         const Expr *E,
110                                                         QualType T,
111                                                         unsigned Count) {
112   
113   if (!SymbolManager::canSymbolicate(T))
114     return UnknownVal();
115
116   SymbolRef sym = SymMgr.getConjuredSymbol(E, T, Count, SymbolTag);
117
118   if (Loc::IsLocType(T))
119     return loc::MemRegionVal(MemMgr.getSymbolicRegion(sym));
120
121   return nonloc::SymbolVal(sym);
122 }
123
124
125 DefinedOrUnknownSVal
126 ValueManager::getDerivedRegionValueSymbolVal(SymbolRef parentSymbol,
127                                              const TypedRegion *R) {
128   QualType T = R->getValueType(R->getContext());
129
130   if (!SymbolManager::canSymbolicate(T))
131     return UnknownVal();
132
133   SymbolRef sym = SymMgr.getDerivedSymbol(parentSymbol, R);
134
135   if (Loc::IsLocType(T))
136     return loc::MemRegionVal(MemMgr.getSymbolicRegion(sym));
137
138   return nonloc::SymbolVal(sym);
139 }
140
141 DefinedSVal ValueManager::getFunctionPointer(const FunctionDecl* FD) {
142   return loc::MemRegionVal(MemMgr.getFunctionTextRegion(FD));
143 }
144
145 DefinedSVal ValueManager::getBlockPointer(const BlockDecl *D,
146                                           CanQualType locTy,
147                                           const LocationContext *LC) {
148   const BlockTextRegion *BC =
149     MemMgr.getBlockTextRegion(D, locTy, LC->getAnalysisContext());
150   const BlockDataRegion *BD = MemMgr.getBlockDataRegion(BC, LC);
151   return loc::MemRegionVal(BD);
152 }
153