blob: c9e24223df11bb233beda4c8183303a10688811a [file] [log] [blame]
Zhongxing Xu2ace5cd2009-06-23 06:22:22 +00001//== 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/Analysis/PathSensitive/ValueManager.h"
17
18using namespace clang;
19using namespace llvm;
20
21//===----------------------------------------------------------------------===//
22// Utility methods for constructing SVals.
23//===----------------------------------------------------------------------===//
24
25SVal ValueManager::makeZeroVal(QualType T) {
26 if (Loc::IsLocType(T))
Zhongxing Xud91ee272009-06-23 09:02:15 +000027 return makeNull();
Zhongxing Xu2ace5cd2009-06-23 06:22:22 +000028
29 if (T->isIntegerType())
Zhongxing Xud91ee272009-06-23 09:02:15 +000030 return makeIntVal(0, T);
Zhongxing Xu2ace5cd2009-06-23 06:22:22 +000031
32 // FIXME: Handle floats.
33 // FIXME: Handle structs.
34 return UnknownVal();
35}
36
Zhongxing Xu2ace5cd2009-06-23 06:22:22 +000037//===----------------------------------------------------------------------===//
38// Utility methods for constructing Non-Locs.
39//===----------------------------------------------------------------------===//
40
Zhongxing Xu2ace5cd2009-06-23 06:22:22 +000041NonLoc ValueManager::makeNonLoc(const SymExpr *lhs, BinaryOperator::Opcode op,
42 const APSInt& v, QualType T) {
43 // The Environment ensures we always get a persistent APSInt in
44 // BasicValueFactory, so we don't need to get the APSInt from
45 // BasicValueFactory again.
46 assert(!Loc::IsLocType(T));
47 return nonloc::SymExprVal(SymMgr.getSymIntExpr(lhs, op, v, T));
48}
49
50NonLoc ValueManager::makeNonLoc(const SymExpr *lhs, BinaryOperator::Opcode op,
51 const SymExpr *rhs, QualType T) {
52 assert(SymMgr.getType(lhs) == SymMgr.getType(rhs));
53 assert(!Loc::IsLocType(T));
54 return nonloc::SymExprVal(SymMgr.getSymSymExpr(lhs, op, rhs, T));
55}
56
Zhongxing Xu2ace5cd2009-06-23 06:22:22 +000057
58SVal ValueManager::getRegionValueSymbolVal(const MemRegion* R, QualType T) {
59 SymbolRef sym = SymMgr.getRegionValueSymbol(R, T);
60
61 if (const TypedRegion* TR = dyn_cast<TypedRegion>(R)) {
62 if (T.isNull())
63 T = TR->getValueType(SymMgr.getContext());
64
65 // If T is of function pointer type, create a CodeTextRegion wrapping a
66 // symbol.
67 if (T->isFunctionPointerType()) {
Zhongxing Xud91ee272009-06-23 09:02:15 +000068 return loc::MemRegionVal(MemMgr.getCodeTextRegion(sym, T));
Zhongxing Xu2ace5cd2009-06-23 06:22:22 +000069 }
70
71 if (Loc::IsLocType(T))
Zhongxing Xud91ee272009-06-23 09:02:15 +000072 return loc::MemRegionVal(MemMgr.getSymbolicRegion(sym));
Zhongxing Xu2ace5cd2009-06-23 06:22:22 +000073
74 // Only handle integers for now.
75 if (T->isIntegerType() && T->isScalarType())
Zhongxing Xud91ee272009-06-23 09:02:15 +000076 return nonloc::SymbolVal(sym);
Zhongxing Xu2ace5cd2009-06-23 06:22:22 +000077 }
78
79 return UnknownVal();
80}
81
82SVal ValueManager::getConjuredSymbolVal(const Expr* E, unsigned Count) {
83 QualType T = E->getType();
84 SymbolRef sym = SymMgr.getConjuredSymbol(E, Count);
85
86 // If T is of function pointer type, create a CodeTextRegion wrapping a
87 // symbol.
88 if (T->isFunctionPointerType()) {
Zhongxing Xud91ee272009-06-23 09:02:15 +000089 return loc::MemRegionVal(MemMgr.getCodeTextRegion(sym, T));
Zhongxing Xu2ace5cd2009-06-23 06:22:22 +000090 }
91
92 if (Loc::IsLocType(T))
Zhongxing Xud91ee272009-06-23 09:02:15 +000093 return loc::MemRegionVal(MemMgr.getSymbolicRegion(sym));
Zhongxing Xu2ace5cd2009-06-23 06:22:22 +000094
95 if (T->isIntegerType() && T->isScalarType())
Zhongxing Xud91ee272009-06-23 09:02:15 +000096 return nonloc::SymbolVal(sym);
Zhongxing Xu2ace5cd2009-06-23 06:22:22 +000097
98 return UnknownVal();
99}
100
101SVal ValueManager::getConjuredSymbolVal(const Expr* E, QualType T,
102 unsigned Count) {
103
104 SymbolRef sym = SymMgr.getConjuredSymbol(E, T, Count);
105
106 // If T is of function pointer type, create a CodeTextRegion wrapping a
107 // symbol.
108 if (T->isFunctionPointerType()) {
Zhongxing Xud91ee272009-06-23 09:02:15 +0000109 return loc::MemRegionVal(MemMgr.getCodeTextRegion(sym, T));
Zhongxing Xu2ace5cd2009-06-23 06:22:22 +0000110 }
111
112 if (Loc::IsLocType(T))
Zhongxing Xud91ee272009-06-23 09:02:15 +0000113 return loc::MemRegionVal(MemMgr.getSymbolicRegion(sym));
Zhongxing Xu2ace5cd2009-06-23 06:22:22 +0000114
115 if (T->isIntegerType() && T->isScalarType())
Zhongxing Xud91ee272009-06-23 09:02:15 +0000116 return nonloc::SymbolVal(sym);
Zhongxing Xu2ace5cd2009-06-23 06:22:22 +0000117
118 return UnknownVal();
119}
120
Ted Kremenekfb91c702009-07-15 02:27:32 +0000121
122SVal ValueManager::getDerivedRegionValueSymbolVal(SymbolRef parentSymbol,
123 const TypedRegion *R) {
124 SymbolRef sym = SymMgr.getDerivedSymbol(parentSymbol, R);
125
126 QualType T = R->getValueType(R->getContext());
127
128 if (Loc::IsLocType(T))
129 return loc::MemRegionVal(MemMgr.getSymbolicRegion(sym));
130
131 if (T->isIntegerType() && T->isScalarType())
132 return nonloc::SymbolVal(sym);
133
134 return UnknownVal();
135}
136
Zhongxing Xu2ace5cd2009-06-23 06:22:22 +0000137SVal ValueManager::getFunctionPointer(const FunctionDecl* FD) {
138 CodeTextRegion* R
139 = MemMgr.getCodeTextRegion(FD, Context.getPointerType(FD->getType()));
140 return loc::MemRegionVal(R);
141}