aboutsummaryrefslogtreecommitdiff
path: root/lib/Analysis/CFRefCount.cpp
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2008-07-09 18:11:16 +0000
committerTed Kremenek <kremenek@apple.com>2008-07-09 18:11:16 +0000
commit070a825e26a2cdce48098e595a8573eff32977fc (patch)
treeed9799b3d723a2eba79301e93b85ed6ae04fbfe4 /lib/Analysis/CFRefCount.cpp
parent49ff7a1c8c67d56e62d3b4627463b705c0d5008c (diff)
Fix PR2519: correctly handle CFDictionaryCreate.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@53334 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Analysis/CFRefCount.cpp')
-rw-r--r--lib/Analysis/CFRefCount.cpp40
1 files changed, 31 insertions, 9 deletions
diff --git a/lib/Analysis/CFRefCount.cpp b/lib/Analysis/CFRefCount.cpp
index 7a3df3153e..1a57306f86 100644
--- a/lib/Analysis/CFRefCount.cpp
+++ b/lib/Analysis/CFRefCount.cpp
@@ -99,8 +99,8 @@ static bool isNSType(QualType T) {
namespace {
/// ArgEffect is used to summarize a function/method call's effect on a
/// particular argument.
-enum ArgEffect { IncRef, DecRef, DoNothing, StopTracking, MayEscape,
- SelfOwn, Autorelease };
+enum ArgEffect { IncRef, DecRef, DoNothing, DoNothingByRef,
+ StopTracking, MayEscape, SelfOwn, Autorelease };
/// ArgEffects summarizes the effects of a function/method call on all of
/// its arguments.
@@ -423,6 +423,10 @@ class VISIBILITY_HIDDEN RetainSummaryManager {
/// NSPanelII - An IdentifierInfo* representing the identifier "NSPanel."
IdentifierInfo* NSPanelII;
+ /// CFDictionaryCreateII - An IdentifierInfo* representing the indentifier
+ /// "CFDictionaryCreate".
+ IdentifierInfo* CFDictionaryCreateII;
+
/// GCEnabled - Records whether or not the analyzed code runs in GC mode.
const bool GCEnabled;
@@ -517,6 +521,7 @@ public:
: Ctx(ctx),
NSWindowII(&ctx.Idents.get("NSWindow")),
NSPanelII(&ctx.Idents.get("NSPanel")),
+ CFDictionaryCreateII(&ctx.Idents.get("CFDictionaryCreate")),
GCEnabled(gcenabled), StopSummary(0) {
InitializeClassMethodSummaries();
@@ -658,7 +663,7 @@ RetainSummary* RetainSummaryManager::getCFSummary(FunctionDecl* FD,
if (strcmp(FName, "Release") == 0)
return getUnarySummary(FD, cfrelease);
-
+
if (strcmp(FName, "MakeCollectable") == 0)
return getUnarySummary(FD, cfmakecollectable);
@@ -727,10 +732,13 @@ RetainSummary* RetainSummaryManager::getCFSummaryCreateRule(FunctionDecl* FD) {
if (FT && !isCFRefType(FT->getResultType()))
return getPersistentSummary(RetEffect::MakeNoRet());
- // FIXME: Add special-cases for functions that retain/release. For now
- // just handle the default case.
-
assert (ScratchArgs.empty());
+
+ if (FD->getIdentifier() == CFDictionaryCreateII) {
+ ScratchArgs.push_back(std::make_pair(1, DoNothingByRef));
+ ScratchArgs.push_back(std::make_pair(2, DoNothingByRef));
+ }
+
return getPersistentSummary(RetEffect::MakeOwned(true));
}
@@ -1393,17 +1401,30 @@ void CFRefCount::EvalSummary(ExplodedNodeSet<ValueState>& Dst,
// Nuke all arguments passed by reference.
StateMgr.Unbind(StVals, cast<LVal>(V));
#else
- if (lval::DeclVal* DV = dyn_cast<lval::DeclVal>(&V)) {
+ if (lval::DeclVal* DV = dyn_cast<lval::DeclVal>(&V)) {
+
+ if (GetArgE(Summ, idx) == DoNothingByRef)
+ continue;
+
+ // Invalidate the value of the variable passed by reference.
// FIXME: Either this logic should also be replicated in GRSimpleVals
// or should be pulled into a separate "constraint engine."
+
// FIXME: We can have collisions on the conjured symbol if the
// expression *I also creates conjured symbols. We probably want
// to identify conjured symbols by an expression pair: the enclosing
// expression (the context) and the expression itself. This should
- // disambiguate conjured symbols.
+ // disambiguate conjured symbols.
+
+ // Is the invalidated variable something that we were tracking?
+ RVal X = StateMgr.GetRVal(&StVals, *DV);
- // Invalidate the values of all variables passed by reference.
+ if (isa<lval::SymbolVal>(X)) {
+ SymbolID Sym = cast<lval::SymbolVal>(X).getSymbol();
+ SetRefBindings(StVals,RefBFactory.Remove(GetRefBindings(StVals),Sym));
+ }
+
// Set the value of the variable to be a conjured symbol.
unsigned Count = Builder.getCurrentBlockCount();
SymbolID NewSym = Eng.getSymbolManager().getConjuredSymbol(*I, Count);
@@ -1866,6 +1887,7 @@ CFRefCount::RefBindings CFRefCount::Update(RefBindings B, SymbolID sym,
// Fall-through.
+ case DoNothingByRef:
case DoNothing:
if (!isGCEnabled() && V.getKind() == RefVal::Released) {
V = V ^ RefVal::ErrorUseAfterRelease;