blob: 15a1d3659f8133fd587a227728583bb1bd582a90 [file] [log] [blame]
Ted Kremenek8133a262008-07-08 21:46:56 +00001//== Environment.cpp - Map from Expr* 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
14#include "clang/Analysis/PathSensitive/Environment.h"
Ted Kremenekdf9cdf82008-08-20 17:08:29 +000015#include "clang/Analysis/Analyses/LiveVariables.h"
Ted Kremenek8133a262008-07-08 21:46:56 +000016#include "llvm/ADT/ImmutableMap.h"
Ted Kremenekdf9cdf82008-08-20 17:08:29 +000017#include "llvm/Support/Streams.h"
Ted Kremenek8133a262008-07-08 21:46:56 +000018
19using namespace clang;
20
Ted Kremenekd72ee902008-07-10 17:19:18 +000021RVal Environment::GetRVal(Expr* E, BasicValueFactory& BasicVals) const {
22
23 for (;;) {
24
25 switch (E->getStmtClass()) {
26
27 case Stmt::AddrLabelExprClass:
28 return LVal::MakeVal(cast<AddrLabelExpr>(E));
29
30 // ParenExprs are no-ops.
31
32 case Stmt::ParenExprClass:
33 E = cast<ParenExpr>(E)->getSubExpr();
34 continue;
35
36 case Stmt::CharacterLiteralClass: {
37 CharacterLiteral* C = cast<CharacterLiteral>(E);
38 return NonLVal::MakeVal(BasicVals, C->getValue(), C->getType());
39 }
40
41 case Stmt::IntegerLiteralClass: {
42 return NonLVal::MakeVal(BasicVals, cast<IntegerLiteral>(E));
43 }
44
45 case Stmt::StringLiteralClass:
46 return LVal::MakeVal(cast<StringLiteral>(E));
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
Argyrios Kyrtzidis0835a3c2008-08-18 23:01:59 +000052 case Stmt::ImplicitCastExprClass:
53 case Stmt::ExplicitCastExprClass: {
Ted Kremenekd72ee902008-07-10 17:19:18 +000054 CastExpr* C = cast<CastExpr>(E);
55 QualType CT = C->getType();
56 QualType ST = C->getSubExpr()->getType();
57
58 if (CT->isVoidType())
59 return UnknownVal();
60
61 break;
62 }
63
64 // Handle all other Expr* using a lookup.
65
66 default:
67 break;
68 };
69
70 break;
71 }
72
73 return LookupExpr(E);
74}
Ted Kremenek8133a262008-07-08 21:46:56 +000075
Ted Kremenekd72ee902008-07-10 17:19:18 +000076RVal Environment::GetBlkExprRVal(Expr* E, BasicValueFactory& BasicVals) const {
77
78 E = E->IgnoreParens();
79
80 switch (E->getStmtClass()) {
81 case Stmt::CharacterLiteralClass: {
82 CharacterLiteral* C = cast<CharacterLiteral>(E);
83 return NonLVal::MakeVal(BasicVals, C->getValue(), C->getType());
84 }
85
86 case Stmt::IntegerLiteralClass: {
87 return NonLVal::MakeVal(BasicVals, cast<IntegerLiteral>(E));
88 }
89
90 default:
91 return LookupBlkExpr(E);
92 }
93}
Ted Kremenek8133a262008-07-08 21:46:56 +000094
Ted Kremenekd72ee902008-07-10 17:19:18 +000095Environment EnvironmentManager::SetRVal(const Environment& Env, Expr* E, RVal V,
96 bool isBlkExpr, bool Invalidate) {
97 assert (E);
98
99 if (V.isUnknown()) {
100 if (Invalidate)
101 return isBlkExpr ? RemoveBlkExpr(Env, E) : RemoveSubExpr(Env, E);
102 else
103 return Env;
104 }
Ted Kremenek8133a262008-07-08 21:46:56 +0000105
Ted Kremenekd72ee902008-07-10 17:19:18 +0000106 return isBlkExpr ? AddBlkExpr(Env, E, V) : AddSubExpr(Env, E, V);
107}
Ted Kremenekdf9cdf82008-08-20 17:08:29 +0000108
109Environment
110EnvironmentManager::RemoveDeadBindings(Environment Env,
111 Stmt* Loc,
112 const LiveVariables& Liveness,
113 StoreManager::DeclRootsTy& DRoots,
114 StoreManager::LiveSymbolsTy& LSymbols) {
115 // Drop bindings for subexpressions.
116 Env = RemoveSubExprBindings(Env);
117
118 // Iterate over the block-expr bindings.
119 for (Environment::beb_iterator I = Env.beb_begin(), E = Env.beb_end();
120 I != E; ++I) {
121 Expr* BlkExpr = I.getKey();
122
123 if (Liveness.isLive(Loc, BlkExpr)) {
124 RVal X = I.getData();
125
126 // If the block expr's value is the address of some Decl, then mark that
127 // Decl.
128 if (isa<lval::DeclVal>(X)) {
129 lval::DeclVal LV = cast<lval::DeclVal>(X);
130 DRoots.push_back(LV.getDecl());
131 }
132
133 // Mark all symbols in the block expr's value.
134 for (RVal::symbol_iterator SI = X.symbol_begin(), SE = X.symbol_end();
135 SI != SE; ++SI) {
136 LSymbols.insert(*SI);
137 }
138 } else {
139 // The block expr is dead.
140 RVal X = I.getData();
141
Zhongxing Xua950fe22008-08-21 23:00:21 +0000142 // Do not misclean LogicalExpr or ConditionalOperator. It is dead at the
143 // beginning of itself, but we need its UndefinedVal to determine its
144 // RVal.
Ted Kremenekdf9cdf82008-08-20 17:08:29 +0000145
146 if (X.isUndef() && cast<UndefinedVal>(X).getData())
147 continue;
148
149 Env = RemoveBlkExpr(Env, BlkExpr);
150 }
151 }
152
153 return Env;
154}