[cfe-commits] r161603 - in /cfe/trunk: include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h lib/StaticAnalyzer/Core/CallEvent.cpp lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
Anna Zaks
ganna at apple.com
Thu Aug 9 11:43:01 PDT 2012
Author: zaks
Date: Thu Aug 9 13:43:00 2012
New Revision: 161603
URL: http://llvm.org/viewvc/llvm-project?rev=161603&view=rev
Log:
[analyzer] Improve readability of the dyn. dispatch bifurcation patch
r161552.
As per Jordan's feedback.
Modified:
cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp
cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h?rev=161603&r1=161602&r2=161603&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h Thu Aug 9 13:43:00 2012
@@ -68,15 +68,24 @@
}
};
+/// \brief Defines the runtime definition of the called function.
class RuntimeDefinition {
+ /// The Declaration of the function which will be called at runtime.
+ /// 0 if not available.
const Decl *D;
+
+ /// The region representing an object (ObjC/C++) on which the method is
+ /// called. With dynamic dispatch, the method definition depends on the
+ /// runtime type of this object. 0 when there is no dynamic dispatch.
const MemRegion *R;
+
public:
RuntimeDefinition(): D(0), R(0) {}
RuntimeDefinition(const Decl *InD): D(InD), R(0) {}
RuntimeDefinition(const Decl *InD, const MemRegion *InR): D(InD), R(InR) {}
- const Decl *getDecl() { return D;}
- const MemRegion *getReg() {return R;}
+ const Decl *getDecl() { return D; }
+ const MemRegion *getDispatchRegion() { return R; }
+ bool mayHaveOtherDefinitions() { return R != 0; }
};
/// \brief Represents an abstract call to a function or method along a
@@ -170,8 +179,7 @@
}
/// \brief Returns the definition of the function or method that will be
- /// called. Returns NULL if the definition cannot be found; ex: due to
- /// dynamic dispatch in ObjC methods.
+ /// called.
virtual RuntimeDefinition getRuntimeDefinition() const = 0;
/// \brief Returns the expression whose value will be the result of this call.
@@ -351,7 +359,7 @@
const FunctionDecl *FD = getDecl();
// Note that hasBody() will fill FD with the definition FunctionDecl.
if (FD && FD->hasBody(FD))
- return RuntimeDefinition(FD, 0);
+ return RuntimeDefinition(FD);
return RuntimeDefinition();
}
@@ -557,7 +565,7 @@
}
virtual RuntimeDefinition getRuntimeDefinition() const {
- return RuntimeDefinition(getBlockDecl(), 0);
+ return RuntimeDefinition(getBlockDecl());
}
virtual void getInitialStackFrameContents(const StackFrameContext *CalleeCtx,
Modified: cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp?rev=161603&r1=161602&r2=161603&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp Thu Aug 9 13:43:00 2012
@@ -389,7 +389,7 @@
const CXXMethodDecl *MD = cast<CXXMethodDecl>(D);
if (!MD->isVirtual())
- return RuntimeDefinition(MD, 0);
+ return RuntimeDefinition(MD);
// If the method is virtual, see if we can find the actual implementation
// based on context-sensitivity.
@@ -398,7 +398,7 @@
// because a /partially/ constructed object can be referred to through a
// base pointer. We'll eventually want to use DynamicTypeInfo here.
if (const CXXMethodDecl *Devirtualized = devirtualize(MD, getCXXThisVal()))
- return RuntimeDefinition(Devirtualized, 0);
+ return RuntimeDefinition(Devirtualized);
return RuntimeDefinition();
}
@@ -519,7 +519,7 @@
const CXXMethodDecl *MD = cast<CXXMethodDecl>(D);
if (!MD->isVirtual())
- return RuntimeDefinition(MD, 0);
+ return RuntimeDefinition(MD);
// If the method is virtual, see if we can find the actual implementation
// based on context-sensitivity.
@@ -528,7 +528,7 @@
// because a /partially/ constructed object can be referred to through a
// base pointer. We'll eventually want to use DynamicTypeInfo here.
if (const CXXMethodDecl *Devirtualized = devirtualize(MD, getCXXThisVal()))
- return RuntimeDefinition(Devirtualized, 0);
+ return RuntimeDefinition(Devirtualized);
return RuntimeDefinition();
}
@@ -695,7 +695,7 @@
// class name.
if (ObjCInterfaceDecl *IDecl = E->getReceiverInterface()) {
// Find/Return the method implementation.
- return RuntimeDefinition(IDecl->lookupPrivateClassMethod(Sel), 0);
+ return RuntimeDefinition(IDecl->lookupPrivateClassMethod(Sel));
}
}
Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp?rev=161603&r1=161602&r2=161603&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp Thu Aug 9 13:43:00 2012
@@ -534,6 +534,10 @@
ProgramStateRef State = Pred->getState();
CallEventRef<> Call = CallTemplate.cloneWithState(State);
+ if (!getAnalysisManager().shouldInlineCall()) {
+ conservativeEvalCall(*Call, Bldr, Pred, State);
+ return;
+ }
// Try to inline the call.
// The origin expression here is just used as a kind of checksum;
// this should still be safe even for CallEvents that don't come from exprs.
@@ -543,21 +547,19 @@
if (InlinedFailedState) {
// If we already tried once and failed, make sure we don't retry later.
State = InlinedFailedState;
- } else if (getAnalysisManager().shouldInlineCall()) {
+ } else {
RuntimeDefinition RD = Call->getRuntimeDefinition();
const Decl *D = RD.getDecl();
if (D) {
// Explore with and without inlining the call.
- const MemRegion *BifurReg = RD.getReg();
- if (BifurReg &&
+ if (RD.mayHaveOtherDefinitions() &&
getAnalysisManager().IPAMode == DynamicDispatchBifurcate) {
- BifurcateCall(BifurReg, *Call, D, Bldr, Pred);
+ BifurcateCall(RD.getDispatchRegion(), *Call, D, Bldr, Pred);
return;
- } else {
- // We are not bifurcating and we do have a Decl, so just inline.
- if (inlineCall(*Call, D, Bldr, Pred, State))
- return;
}
+ // We are not bifurcating and we do have a Decl, so just inline.
+ if (inlineCall(*Call, D, Bldr, Pred, State))
+ return;
}
}
@@ -573,20 +575,17 @@
// Check if we've performed the split already - note, we only want
// to split the path once per memory region.
ProgramStateRef State = Pred->getState();
- DynamicDispatchBifur BM = State->get<DynamicDispatchBifurcationMap>();
- for (DynamicDispatchBifur::iterator I = BM.begin(),
- E = BM.end(); I != E; ++I) {
- if (I->first == BifurReg) {
- // If we are on "inline path", keep inlining if possible.
- if (I->second == true)
- if (inlineCall(Call, D, Bldr, Pred, State))
- return;
- // If inline failed, or we are on the path where we assume we
- // don't have enough info about the receiver to inline, conjure the
- // return value and invalidate the regions.
- conservativeEvalCall(Call, Bldr, Pred, State);
- return;
- }
+ const int *BState = State->get<DynamicDispatchBifurcationMap>(BifurReg);
+ if (BState) {
+ // If we are on "inline path", keep inlining if possible.
+ if (*BState == true)
+ if (inlineCall(Call, D, Bldr, Pred, State))
+ return;
+ // If inline failed, or we are on the path where we assume we
+ // don't have enough info about the receiver to inline, conjure the
+ // return value and invalidate the regions.
+ conservativeEvalCall(Call, Bldr, Pred, State);
+ return;
}
// If we got here, this is the first time we process a message to this
More information about the cfe-commits
mailing list