Changed behavior of how we handle "NULL" summaries: just call

GRSimpleVals::EvalCal(), and don't change reference counts.

Remove "getDoNothingSummary()", as a NULL summary does the same thing.

Added temporary hack for the "Get" rule for objects that return a pointer type:
treat them as non-owned CF objects.

Added test case to detect the release of a non-owned object.

llvm-svn: 49555
This commit is contained in:
Ted Kremenek 2008-04-11 20:11:19 +00:00
parent 5a4611cdda
commit a7c44113bc
2 changed files with 46 additions and 9 deletions

View File

@ -136,7 +136,6 @@ class CFRefSummaryManager {
CFRefSummary* getPersistentSummary(ArgEffects* AE, RetEffect RE);
CFRefSummary* getDoNothingSummary(unsigned Args);
void FillDoNothing(unsigned Args);
@ -366,16 +365,12 @@ void CFRefSummaryManager::FillDoNothing(unsigned Args) {
ScratchArgs.push_back(DoNothing);
}
CFRefSummary* CFRefSummaryManager::getDoNothingSummary(unsigned Args) {
FillDoNothing(Args);
return getPersistentSummary(getArgEffects(), RetEffect::MakeNoRet());
}
CFRefSummary*
CFRefSummaryManager::getCFSummaryCreateRule(FunctionTypeProto* FT) {
if (!isCFRefType(FT->getResultType()))
return getDoNothingSummary(FT->getNumArgs());
return NULL;
assert (ScratchArgs.empty());
@ -389,8 +384,16 @@ CFRefSummaryManager::getCFSummaryCreateRule(FunctionTypeProto* FT) {
CFRefSummary*
CFRefSummaryManager::getCFSummaryGetRule(FunctionTypeProto* FT) {
if (!isCFRefType(FT->getResultType()))
return getDoNothingSummary(FT->getNumArgs());
QualType RetTy = FT->getResultType();
// FIXME: For now we assume that all pointer types returned are referenced
// counted. Since this is the "Get" rule, we assume non-ownership, which
// works fine for things that are not reference counted. We do this because
// some generic data structures return "void*". We need something better
// in the future.
if (!isCFRefType(RetTy) && !RetTy->isPointerType())
return NULL;
assert (ScratchArgs.empty());
@ -659,7 +662,7 @@ void CFRefCount::EvalCall(ExplodedNodeSet<ValueState>& Dst,
RefVal::Kind hasError = (RefVal::Kind) 0;
if (!Summ) {
#if 0
// This function has no summary. Invalidate all reference-count state
// for arguments passed to this function, and also nuke the values of
// arguments passed-by-reference.
@ -698,6 +701,10 @@ void CFRefCount::EvalCall(ExplodedNodeSet<ValueState>& Dst,
Builder.MakeNode(Dst, CE, Pred, St);
return;
#else
GRSimpleVals::EvalCall(Dst, Eng, Builder, CE, L, Pred);
return;
#endif
}
// This function has a summary. Evaluate the effect of the arguments.

View File

@ -0,0 +1,30 @@
// RUN: clang -checker-cfref -verify %s
#include <CoreFoundation/CFString.h>
#include <CoreFoundation/CFArray.h>
void f1() {
// Create the array.
CFMutableArrayRef A = CFArrayCreateMutable(NULL, 10, &kCFTypeArrayCallBacks);
// Create a string.
CFStringRef s1 = CFStringCreateWithCString(NULL, "hello world",
kCFStringEncodingUTF8);
// Add the string to the array.
CFArrayAppendValue(A, s1);
// Decrement the reference count.
CFRelease(s1); // no-warning
// Get the string. We don't own it.
s1 = (CFStringRef) CFArrayGetValueAtIndex(A, 0);
// Release the array.
CFRelease(A); // no-warning
// Release the string. This is a bug.
CFRelease(s1); // expected-warning{{Incorrect decrement of the reference count}}
}