blob: a67965e35a17ed411d4ebe9f915b5ee87f3c034d [file] [log] [blame]
Ted Kremenekd4931632008-11-12 19:21:30 +00001//== Environment.cpp - Map from Stmt* to Locations/Values -------*- C++ -*--==//
Ted Kremenek8133a262008-07-08 21:46:56 +00002//
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 Kremenekd4931632008-11-12 19:21:30 +000021SVal Environment::GetSVal(Stmt* E, BasicValueFactory& BasicVals) const {
Ted Kremenekd72ee902008-07-10 17:19:18 +000022
23 for (;;) {
24
25 switch (E->getStmtClass()) {
26
27 case Stmt::AddrLabelExprClass:
Zhongxing Xu1c96b242008-10-17 05:57:07 +000028 return Loc::MakeVal(cast<AddrLabelExpr>(E));
Ted Kremenekd72ee902008-07-10 17:19:18 +000029
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);
Zhongxing Xu1c96b242008-10-17 05:57:07 +000038 return NonLoc::MakeVal(BasicVals, C->getValue(), C->getType());
Ted Kremenekd72ee902008-07-10 17:19:18 +000039 }
40
41 case Stmt::IntegerLiteralClass: {
Zhongxing Xu1c96b242008-10-17 05:57:07 +000042 return NonLoc::MakeVal(BasicVals, cast<IntegerLiteral>(E));
Ted Kremenekd72ee902008-07-10 17:19:18 +000043 }
44
Zhongxing Xu143bf822008-10-25 14:18:57 +000045 // Casts where the source and target type are the same
46 // are no-ops. We blast through these to get the descendant
47 // subexpression that has a value.
48
Argyrios Kyrtzidis0835a3c2008-08-18 23:01:59 +000049 case Stmt::ImplicitCastExprClass:
Douglas Gregor6eec8e82008-10-28 15:36:24 +000050 case Stmt::CStyleCastExprClass: {
Ted Kremenekd72ee902008-07-10 17:19:18 +000051 CastExpr* C = cast<CastExpr>(E);
52 QualType CT = C->getType();
53 QualType ST = C->getSubExpr()->getType();
54
55 if (CT->isVoidType())
56 return UnknownVal();
57
58 break;
59 }
60
Ted Kremenekd4931632008-11-12 19:21:30 +000061 // Handle all other Stmt* using a lookup.
Ted Kremenekd72ee902008-07-10 17:19:18 +000062
63 default:
64 break;
65 };
66
67 break;
68 }
69
70 return LookupExpr(E);
71}
Ted Kremenek8133a262008-07-08 21:46:56 +000072
Ted Kremenekd4931632008-11-12 19:21:30 +000073SVal Environment::GetBlkExprSVal(Stmt* E, BasicValueFactory& BasicVals) const {
Ted Kremenekd72ee902008-07-10 17:19:18 +000074
Ted Kremenekd4931632008-11-12 19:21:30 +000075 while (1) {
76 switch (E->getStmtClass()) {
77 case Stmt::ParenExprClass:
78 E = cast<ParenExpr>(E)->getSubExpr();
79 continue;
80
81 case Stmt::CharacterLiteralClass: {
82 CharacterLiteral* C = cast<CharacterLiteral>(E);
83 return NonLoc::MakeVal(BasicVals, C->getValue(), C->getType());
84 }
85
86 case Stmt::IntegerLiteralClass: {
87 return NonLoc::MakeVal(BasicVals, cast<IntegerLiteral>(E));
88 }
89
90 default:
91 return LookupBlkExpr(E);
Ted Kremenekd72ee902008-07-10 17:19:18 +000092 }
Ted Kremenekd72ee902008-07-10 17:19:18 +000093 }
94}
Ted Kremenek8133a262008-07-08 21:46:56 +000095
Ted Kremenekd4931632008-11-12 19:21:30 +000096Environment EnvironmentManager::BindExpr(const Environment& Env, Stmt* E,SVal V,
Zhongxing Xu8cd5aae2008-10-30 05:33:54 +000097 bool isBlkExpr, bool Invalidate) {
Ted Kremenekd72ee902008-07-10 17:19:18 +000098 assert (E);
99
100 if (V.isUnknown()) {
101 if (Invalidate)
102 return isBlkExpr ? RemoveBlkExpr(Env, E) : RemoveSubExpr(Env, E);
103 else
104 return Env;
105 }
Ted Kremenek8133a262008-07-08 21:46:56 +0000106
Ted Kremenekd72ee902008-07-10 17:19:18 +0000107 return isBlkExpr ? AddBlkExpr(Env, E, V) : AddSubExpr(Env, E, V);
108}
Ted Kremenekdf9cdf82008-08-20 17:08:29 +0000109
110Environment
Ted Kremenek9e240492008-10-04 05:50:14 +0000111EnvironmentManager::RemoveDeadBindings(Environment Env, Stmt* Loc,
112 const LiveVariables& Liveness,
113 llvm::SmallVectorImpl<const MemRegion*>& DRoots,
114 StoreManager::LiveSymbolsTy& LSymbols) {
115
Ted Kremenekdf9cdf82008-08-20 17:08:29 +0000116 // Drop bindings for subexpressions.
117 Env = RemoveSubExprBindings(Env);
118
119 // Iterate over the block-expr bindings.
120 for (Environment::beb_iterator I = Env.beb_begin(), E = Env.beb_end();
121 I != E; ++I) {
Ted Kremenekd4931632008-11-12 19:21:30 +0000122 Stmt* BlkExpr = I.getKey();
Ted Kremenekdf9cdf82008-08-20 17:08:29 +0000123
124 if (Liveness.isLive(Loc, BlkExpr)) {
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000125 SVal X = I.getData();
Ted Kremenekdf9cdf82008-08-20 17:08:29 +0000126
Ted Kremenek9e240492008-10-04 05:50:14 +0000127 // If the block expr's value is a memory region, then mark that region.
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000128 if (isa<loc::MemRegionVal>(X))
129 DRoots.push_back(cast<loc::MemRegionVal>(X).getRegion());
Ted Kremenek9e240492008-10-04 05:50:14 +0000130
Ted Kremenekdf9cdf82008-08-20 17:08:29 +0000131
132 // Mark all symbols in the block expr's value.
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000133 for (SVal::symbol_iterator SI = X.symbol_begin(), SE = X.symbol_end();
Ted Kremenekdf9cdf82008-08-20 17:08:29 +0000134 SI != SE; ++SI) {
135 LSymbols.insert(*SI);
136 }
137 } else {
138 // The block expr is dead.
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000139 SVal X = I.getData();
Ted Kremenekdf9cdf82008-08-20 17:08:29 +0000140
Zhongxing Xua950fe22008-08-21 23:00:21 +0000141 // Do not misclean LogicalExpr or ConditionalOperator. It is dead at the
142 // beginning of itself, but we need its UndefinedVal to determine its
Zhongxing Xu1c96b242008-10-17 05:57:07 +0000143 // SVal.
Ted Kremenekdf9cdf82008-08-20 17:08:29 +0000144
145 if (X.isUndef() && cast<UndefinedVal>(X).getData())
146 continue;
147
148 Env = RemoveBlkExpr(Env, BlkExpr);
149 }
150 }
151
152 return Env;
153}