1 //=-- ExprEngineCallAndReturn.cpp - Support for call/return -----*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file defines ExprEngine's support for calls and returns.
12 //===----------------------------------------------------------------------===//
14 #include "clang/StaticAnalyzer/Core/CheckerManager.h"
15 #include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"
16 #include "clang/StaticAnalyzer/Core/PathSensitive/ObjCMessage.h"
17 #include "clang/AST/DeclCXX.h"
18 #include "clang/Analysis/Support/SaveAndRestore.h"
20 using namespace clang;
24 // Trait class for recording returned expression in the state.
27 typedef const Stmt *data_type;
29 int ReturnExpr::TagInt;
32 void ExprEngine::processCallEnter(CallEnterNodeBuilder &B) {
33 const ProgramState *state =
34 B.getState()->enterStackFrame(B.getCalleeContext());
35 B.generateNode(state);
38 void ExprEngine::processCallExit(CallExitNodeBuilder &B) {
39 const ProgramState *state = B.getState();
40 const ExplodedNode *Pred = B.getPredecessor();
41 const StackFrameContext *calleeCtx =
42 cast<StackFrameContext>(Pred->getLocationContext());
43 const Stmt *CE = calleeCtx->getCallSite();
45 // If the callee returns an expression, bind its value to CallExpr.
46 const Stmt *ReturnedExpr = state->get<ReturnExpr>();
48 SVal RetVal = state->getSVal(ReturnedExpr);
49 state = state->BindExpr(CE, RetVal);
50 // Clear the return expr GDM.
51 state = state->remove<ReturnExpr>();
54 // Bind the constructed object value to CXXConstructExpr.
55 if (const CXXConstructExpr *CCE = dyn_cast<CXXConstructExpr>(CE)) {
56 const CXXThisRegion *ThisR =
57 getCXXThisRegion(CCE->getConstructor()->getParent(), calleeCtx);
59 SVal ThisV = state->getSVal(ThisR);
60 // Always bind the region to the CXXConstructExpr.
61 state = state->BindExpr(CCE, ThisV);
64 B.generateNode(state);
68 ExprEngine::invalidateArguments(const ProgramState *State,
69 const CallOrObjCMessage &Call,
70 const LocationContext *LC) {
71 SmallVector<const MemRegion *, 8> RegionsToInvalidate;
73 if (Call.isObjCMessage()) {
74 // Invalidate all instance variables of the receiver of an ObjC message.
75 // FIXME: We should be able to do better with inter-procedural analysis.
76 if (const MemRegion *MR = Call.getInstanceMessageReceiver(LC).getAsRegion())
77 RegionsToInvalidate.push_back(MR);
79 } else if (Call.isCXXCall()) {
80 // Invalidate all instance variables for the callee of a C++ method call.
81 // FIXME: We should be able to do better with inter-procedural analysis.
82 // FIXME: We can probably do better for const versus non-const methods.
83 if (const MemRegion *Callee = Call.getCXXCallee().getAsRegion())
84 RegionsToInvalidate.push_back(Callee);
86 } else if (Call.isFunctionCall()) {
87 // Block calls invalidate all captured-by-reference values.
88 if (const MemRegion *Callee = Call.getFunctionCallee().getAsRegion()) {
89 if (isa<BlockDataRegion>(Callee))
90 RegionsToInvalidate.push_back(Callee);
94 for (unsigned idx = 0, e = Call.getNumArgs(); idx != e; ++idx) {
95 SVal V = Call.getArgSVal(idx);
97 // If we are passing a location wrapped as an integer, unwrap it and
98 // invalidate the values referred by the location.
99 if (nonloc::LocAsInteger *Wrapped = dyn_cast<nonloc::LocAsInteger>(&V))
100 V = Wrapped->getLoc();
101 else if (!isa<Loc>(V))
104 if (const MemRegion *R = V.getAsRegion()) {
105 // Invalidate the value of the variable passed by reference.
107 // Are we dealing with an ElementRegion? If the element type is
108 // a basic integer type (e.g., char, int) and the underying region
109 // is a variable region then strip off the ElementRegion.
110 // FIXME: We really need to think about this for the general case
111 // as sometimes we are reasoning about arrays and other times
112 // about (char*), etc., is just a form of passing raw bytes.
113 // e.g., void *p = alloca(); foo((char*)p);
114 if (const ElementRegion *ER = dyn_cast<ElementRegion>(R)) {
115 // Checking for 'integral type' is probably too promiscuous, but
116 // we'll leave it in for now until we have a systematic way of
117 // handling all of these cases. Eventually we need to come up
118 // with an interface to StoreManager so that this logic can be
119 // approriately delegated to the respective StoreManagers while
120 // still allowing us to do checker-specific logic (e.g.,
121 // invalidating reference counts), probably via callbacks.
122 if (ER->getElementType()->isIntegralOrEnumerationType()) {
123 const MemRegion *superReg = ER->getSuperRegion();
124 if (isa<VarRegion>(superReg) || isa<FieldRegion>(superReg) ||
125 isa<ObjCIvarRegion>(superReg))
126 R = cast<TypedRegion>(superReg);
128 // FIXME: What about layers of ElementRegions?
131 // Mark this region for invalidation. We batch invalidate regions
132 // below for efficiency.
133 RegionsToInvalidate.push_back(R);
135 // Nuke all other arguments passed by reference.
136 // FIXME: is this necessary or correct? This handles the non-Region
137 // cases. Is it ever valid to store to these?
138 State = State->unbindLoc(cast<Loc>(V));
142 // Invalidate designated regions using the batch invalidation API.
144 // FIXME: We can have collisions on the conjured symbol if the
145 // expression *I also creates conjured symbols. We probably want
146 // to identify conjured symbols by an expression pair: the enclosing
147 // expression (the context) and the expression itself. This should
148 // disambiguate conjured symbols.
149 assert(Builder && "Invalidating arguments outside of a statement context");
150 unsigned Count = Builder->getCurrentBlockCount();
151 StoreManager::InvalidatedSymbols IS;
153 // NOTE: Even if RegionsToInvalidate is empty, we may still invalidate
155 return State->invalidateRegions(RegionsToInvalidate,
156 Call.getOriginExpr(), Count,
157 &IS, doesInvalidateGlobals(Call));
161 void ExprEngine::VisitCallExpr(const CallExpr *CE, ExplodedNode *Pred,
162 ExplodedNodeSet &dst) {
163 // Perform the previsit of the CallExpr.
164 ExplodedNodeSet dstPreVisit;
165 getCheckerManager().runCheckersForPreStmt(dstPreVisit, Pred, CE, *this);
167 // Now evaluate the call itself.
168 class DefaultEval : public GraphExpander {
173 DefaultEval(ExprEngine &eng, const CallExpr *ce)
174 : Eng(eng), CE(ce) {}
175 virtual void expandGraph(ExplodedNodeSet &Dst, ExplodedNode *Pred) {
176 // Should we inline the call?
177 if (Eng.getAnalysisManager().shouldInlineCall() &&
178 Eng.InlineCall(Dst, CE, Pred)) {
182 // First handle the return value.
183 StmtNodeBuilder &Builder = Eng.getBuilder();
184 assert(&Builder && "StmtNodeBuilder must be defined.");
187 const Expr *Callee = CE->getCallee()->IgnoreParens();
188 const ProgramState *state = Pred->getState();
189 SVal L = state->getSVal(Callee);
191 // Figure out the result type. We do this dance to handle references.
193 if (const FunctionDecl *FD = L.getAsFunctionDecl())
194 ResultTy = FD->getResultType();
196 ResultTy = CE->getType();
199 ResultTy = Eng.getContext().getPointerType(ResultTy);
201 // Conjure a symbol value to use as the result.
202 SValBuilder &SVB = Eng.getSValBuilder();
203 unsigned Count = Builder.getCurrentBlockCount();
204 SVal RetVal = SVB.getConjuredSymbolVal(0, CE, ResultTy, Count);
206 // Generate a new state with the return value set.
207 state = state->BindExpr(CE, RetVal);
209 // Invalidate the arguments.
210 const LocationContext *LC = Pred->getLocationContext();
211 state = Eng.invalidateArguments(state, CallOrObjCMessage(CE, state), LC);
213 // And make the result node.
214 Eng.MakeNode(Dst, CE, Pred, state);
218 // Finally, evaluate the function call. We try each of the checkers
219 // to see if the can evaluate the function call.
220 ExplodedNodeSet dstCallEvaluated;
221 DefaultEval defEval(*this, CE);
222 getCheckerManager().runCheckersForEvalCall(dstCallEvaluated,
224 CE, *this, &defEval);
226 // Finally, perform the post-condition check of the CallExpr and store
227 // the created nodes in 'Dst'.
228 getCheckerManager().runCheckersForPostStmt(dst, dstCallEvaluated, CE,
232 void ExprEngine::VisitReturnStmt(const ReturnStmt *RS, ExplodedNode *Pred,
233 ExplodedNodeSet &Dst) {
235 if (const Expr *RetE = RS->getRetValue()) {
236 // Record the returned expression in the state. It will be used in
237 // processCallExit to bind the return value to the call expr.
239 static SimpleProgramPointTag tag("ExprEngine: ReturnStmt");
240 const ProgramState *state = Pred->getState();
241 state = state->set<ReturnExpr>(RetE);
242 Pred = Builder->generateNode(RetE, state, Pred, &tag);
244 // We may get a NULL Pred because we generated a cached node.
246 Visit(RetE, Pred, Src);
252 getCheckerManager().runCheckersForPreStmt(Dst, Src, RS, *this);