 |
|
 |
|
| Files: |
1 |
|
Branches Taken: |
77.8% |
28 / 36 |
| Generated: |
2010-02-10 01:31 |
|
Branches Executed: |
94.4% |
34 / 36 |
| |
|
Line Coverage: |
93.8% |
45 / 48 |
| |
 |
|
 |
1 : //== Environment.cpp - Map from Stmt* to Locations/Values -------*- 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 defined the Environment and EnvironmentManager classes.
11 : //
12 : //===----------------------------------------------------------------------===//
13 : #include "clang/Checker/PathSensitive/GRState.h"
14 : #include "clang/Analysis/Analyses/LiveVariables.h"
15 : #include "llvm/ADT/ImmutableMap.h"
16 :
17 : using namespace clang;
18 :
19 62723: SVal Environment::GetSVal(const Stmt *E, ValueManager& ValMgr) const {
20 :
21 1028: for (;;) {
22 :
0: branch 1 not taken
1028: branch 2 taken
58: branch 3 taken
5114: branch 4 taken
22634: branch 5 taken
33889: branch 6 taken
23 62723: switch (E->getStmtClass()) {
24 :
25 : case Stmt::AddrLabelExprClass:
26 0: return ValMgr.makeLoc(cast<AddrLabelExpr>(E));
27 :
28 : // ParenExprs are no-ops.
29 :
30 : case Stmt::ParenExprClass:
31 1028: E = cast<ParenExpr>(E)->getSubExpr();
32 : continue;
33 :
34 : case Stmt::CharacterLiteralClass: {
35 58: const CharacterLiteral* C = cast<CharacterLiteral>(E);
36 58: return ValMgr.makeIntVal(C->getValue(), C->getType());
37 : }
38 :
39 : case Stmt::IntegerLiteralClass: {
40 : // In C++, this expression may have been bound to a temporary object.
41 5114: SVal const *X = ExprBindings.lookup(E);
1: branch 0 taken
5113: branch 1 taken
42 5114: if (X)
43 1: return *X;
44 : else
45 5113: return ValMgr.makeIntVal(cast<IntegerLiteral>(E));
46 : }
47 :
48 : // Casts where the source and target type are the same
49 : // are no-ops. We blast through these to get the descendant
50 : // subexpression that has a value.
51 :
52 : case Stmt::ImplicitCastExprClass:
53 : case Stmt::CStyleCastExprClass: {
54 22634: const CastExpr* C = cast<CastExpr>(E);
55 22634: QualType CT = C->getType();
56 :
18: branch 2 taken
22616: branch 3 taken
57 22634: if (CT->isVoidType())
58 18: return UnknownVal();
59 :
60 : break;
61 : }
62 :
63 : // Handle all other Stmt* using a lookup.
64 :
65 : default:
66 : break;
67 : };
68 :
69 : break;
70 : }
71 :
72 56505: return LookupExpr(E);
73 : }
74 :
75 : Environment EnvironmentManager::BindExpr(Environment Env, const Stmt *S,
76 28058: SVal V, bool Invalidate) {
0: branch 0 not taken
28058: branch 1 taken
77 28058: assert(S);
78 :
1110: branch 1 taken
26948: branch 2 taken
79 28058: if (V.isUnknown()) {
1110: branch 0 taken
0: branch 1 not taken
80 1110: if (Invalidate)
81 1110: return Environment(F.Remove(Env.ExprBindings, S), Env.ACtx);
82 : else
83 0: return Env;
84 : }
85 :
86 26948: return Environment(F.Add(Env.ExprBindings, S, V), Env.ACtx);
87 : }
88 :
89 : namespace {
0: branch 1 not taken
0: branch 2 not taken
0: branch 5 not taken
2437: branch 6 taken
90 2437: class MarkLiveCallback : public SymbolVisitor {
91 : SymbolReaper &SymReaper;
92 : public:
93 2437: MarkLiveCallback(SymbolReaper &symreaper) : SymReaper(symreaper) {}
94 1202: bool VisitSymbol(SymbolRef sym) { SymReaper.markLive(sym); return true; }
95 : };
96 : } // end anonymous namespace
97 :
98 : // RemoveDeadBindings:
99 : // - Remove subexpression bindings.
100 : // - Remove dead block expression bindings.
101 : // - Keep live block expression bindings:
102 : // - Mark their reachable symbols live in SymbolReaper,
103 : // see ScanReachableSymbols.
104 : // - Mark the region in DRoots if the binding is a loc::MemRegionVal.
105 :
106 : Environment
107 : EnvironmentManager::RemoveDeadBindings(Environment Env, const Stmt *S,
108 : SymbolReaper &SymReaper,
109 : const GRState *ST,
110 11706: llvm::SmallVectorImpl<const MemRegion*> &DRoots) {
111 :
112 11706: CFG &C = *Env.getAnalysisContext().getCFG();
113 :
114 : // We construct a new Environment object entirely, as this is cheaper than
115 : // individually removing all the subexpression bindings (which will greatly
116 : // outnumber block-level expression bindings).
117 11706: Environment NewEnv = getInitialEnvironment(&Env.getAnalysisContext());
118 :
119 : // Iterate over the block-expr bindings.
24486: branch 4 taken
11706: branch 5 taken
120 36192: for (Environment::iterator I = Env.begin(), E = Env.end();
121 : I != E; ++I) {
122 :
123 24486: const Stmt *BlkExpr = I.getKey();
124 :
125 : // Not a block-level expression?
16506: branch 1 taken
7980: branch 2 taken
126 24486: if (!C.isBlkExpr(BlkExpr))
127 16506: continue;
128 :
129 7980: const SVal &X = I.getData();
130 :
2437: branch 1 taken
5543: branch 2 taken
131 7980: if (SymReaper.isLive(S, BlkExpr)) {
132 : // Copy the binding to the new map.
133 2437: NewEnv.ExprBindings = F.Add(NewEnv.ExprBindings, BlkExpr, X);
134 :
135 : // If the block expr's value is a memory region, then mark that region.
966: branch 1 taken
1471: branch 2 taken
136 2437: if (isa<loc::MemRegionVal>(X)) {
137 966: const MemRegion* R = cast<loc::MemRegionVal>(X).getRegion();
138 966: DRoots.push_back(R);
139 : // Mark the super region of the RX as live.
140 : // e.g.: int x; char *y = (char*) &x; if (*y) ...
141 : // 'y' => element region. 'x' is its super region.
142 : // We only add one level super region for now.
143 :
144 : // FIXME: maybe multiple level of super regions should be added.
966: branch 1 taken
0: branch 2 not taken
145 966: if (const SubRegion *SR = dyn_cast<SubRegion>(R))
146 966: DRoots.push_back(SR->getSuperRegion());
147 : }
148 :
149 : // Mark all symbols in the block expr's value live.
150 2437: MarkLiveCallback cb(SymReaper);
151 2437: ST->scanReachableSymbols(X, cb);
152 2437: continue;
153 : }
154 :
155 : // Otherwise the expression is dead with a couple exceptions.
156 : // Do not misclean LogicalExpr or ConditionalOperator. It is dead at the
157 : // beginning of itself, but we need its UndefinedVal to determine its
158 : // SVal.
699: branch 1 taken
4844: branch 2 taken
699: branch 5 taken
0: branch 6 not taken
699: branch 7 taken
4844: branch 8 taken
159 5543: if (X.isUndef() && cast<UndefinedVal>(X).getData())
160 699: NewEnv.ExprBindings = F.Add(NewEnv.ExprBindings, BlkExpr, X);
161 11706: }
162 :
163 : return NewEnv;
164 0: }
Generated: 2010-02-10 01:31 by zcov