From: Ted Kremenek Date: Wed, 17 Dec 2008 21:50:35 +0000 (+0000) Subject: CF-retain/release checker: X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=2fb78a70536274426302415b6fc54a1074788e91;p=clang CF-retain/release checker: - Fix regression reported in . After a null check, null references to resources should not have a retain count. This regression was caused by removing the call to "GRTransferFuncs::EvalAssume" in BasicConstraintManager. - Added a test case to test this behavior. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@61155 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Analysis/PathSensitive/GRState.h b/include/clang/Analysis/PathSensitive/GRState.h index 71990b0e65..483f16ed7d 100644 --- a/include/clang/Analysis/PathSensitive/GRState.h +++ b/include/clang/Analysis/PathSensitive/GRState.h @@ -325,6 +325,7 @@ public: ASTContext& getContext() { return BasicVals.getContext(); } const Decl& getCodeDecl() { return codedecl; } + GRTransferFuncs& getTransferFuncs() { return *TF; } BasicValueFactory& getBasicVals() { return BasicVals; } const BasicValueFactory& getBasicVals() const { return BasicVals; } SymbolManager& getSymbolManager() { return SymMgr; } diff --git a/lib/Analysis/BasicConstraintManager.cpp b/lib/Analysis/BasicConstraintManager.cpp index 7c303b2ac3..d9d97c601a 100644 --- a/lib/Analysis/BasicConstraintManager.cpp +++ b/lib/Analysis/BasicConstraintManager.cpp @@ -15,6 +15,7 @@ #include "clang/Analysis/PathSensitive/ConstraintManager.h" #include "clang/Analysis/PathSensitive/GRState.h" #include "clang/Analysis/PathSensitive/GRStateTrait.h" +#include "clang/Analysis/PathSensitive/GRTransferFuncs.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/raw_ostream.h" @@ -115,8 +116,15 @@ const GRState* BasicConstraintManager::Assume(const GRState* St, SVal Cond, const GRState* BasicConstraintManager::Assume(const GRState* St, Loc Cond, bool Assumption, bool& isFeasible) { St = AssumeAux(St, Cond, Assumption, isFeasible); - // TF->EvalAssume(*this, St, Cond, Assumption, isFeasible) - return St; + + if (!isFeasible) + return St; + + // EvalAssume is used to call into the GRTransferFunction object to perform + // any checker-specific update of the state based on this assumption being + // true or false. + return StateMgr.getTransferFuncs().EvalAssume(StateMgr, St, Cond, Assumption, + isFeasible); } const GRState* BasicConstraintManager::AssumeAux(const GRState* St, Loc Cond, @@ -173,8 +181,15 @@ const GRState* BasicConstraintManager::Assume(const GRState* St, NonLoc Cond, bool Assumption, bool& isFeasible) { St = AssumeAux(St, Cond, Assumption, isFeasible); - // TF->EvalAssume() does nothing now. - return St; + + if (!isFeasible) + return St; + + // EvalAssume is used to call into the GRTransferFunction object to perform + // any checker-specific update of the state based on this assumption being + // true or false. + return StateMgr.getTransferFuncs().EvalAssume(StateMgr, St, Cond, Assumption, + isFeasible); } const GRState* diff --git a/test/Analysis/NSString.m b/test/Analysis/NSString.m index a56c5b8585..ab503fab89 100644 --- a/test/Analysis/NSString.m +++ b/test/Analysis/NSString.m @@ -15,6 +15,7 @@ typedef const struct __CFAllocator * CFAllocatorRef; extern const CFAllocatorRef kCFAllocatorDefault; extern CFTypeRef CFRetain(CFTypeRef cf); typedef const struct __CFDictionary * CFDictionaryRef; +const void *CFDictionaryGetValue(CFDictionaryRef theDict, const void *key); extern CFStringRef CFStringCreateWithFormat(CFAllocatorRef alloc, CFDictionaryRef formatOptions, CFStringRef format, ...); typedef signed char BOOL; typedef int NSInteger; @@ -27,6 +28,7 @@ typedef struct _NSZone NSZone; @protocol NSObject - (BOOL)isEqual:(id)object; - (oneway void)release; +- (id)retain; @end @protocol NSCopying - (id)copyWithZone:(NSZone *)zone; @@ -132,14 +134,22 @@ void f9() { } NSString* f10() { - static NSString* s = 0; - if (!s) s = [[NSString alloc] init]; - return s; // no-warning } +// Test case for regression reported in . +// Essentially 's' should not be considered allocated on the false branch. +// This exercises the 'EvalAssume' logic in GRTransferFuncs (CFRefCount.cpp). +NSString* f11(CFDictionaryRef dict, const char* key) { + NSString* s = (NSString*) CFDictionaryGetValue(dict, key); + [s retain]; + if (s) { + [s release]; + } +} + @interface C1 : NSObject {} - (NSString*) getShared; + (C1*) sharedInstance;