diff options
author | Anna Zaks <ganna@apple.com> | 2012-02-21 00:00:44 +0000 |
---|---|---|
committer | Anna Zaks <ganna@apple.com> | 2012-02-21 00:00:44 +0000 |
commit | 9c1e1bd0405b990b6e7909647def7b23d5c28f17 (patch) | |
tree | a0ce0a11696c63ba25395f3b367d7e09b663c524 | |
parent | ee0653963537f6ea60f655856fb0c83d7d4010db (diff) |
[analyzer] Make KeyChainAPI checker inlining-aware.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@151007 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp | 12 | ||||
-rw-r--r-- | test/Analysis/keychainAPI.m | 64 |
2 files changed, 73 insertions, 3 deletions
diff --git a/lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp b/lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp index e5f99307a5..bee27ec9ae 100644 --- a/lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp @@ -447,7 +447,8 @@ void MacOSKeychainAPIChecker::checkPostStmt(const CallExpr *CE, const Expr *ArgExpr = CE->getArg(FunctionsToTrack[idx].Param); // If the argument entered as an enclosing function parameter, skip it to // avoid false positives. - if (isEnclosingFunctionParam(ArgExpr)) + if (isEnclosingFunctionParam(ArgExpr) && + C.getLocationContext()->getParent() == 0) return; if (SymbolRef V = getAsPointeeSymbol(ArgExpr, C)) { @@ -481,6 +482,10 @@ void MacOSKeychainAPIChecker::checkPreStmt(const ReturnStmt *S, if (!retExpr) return; + // If inside inlined call, skip it. + if (C.getLocationContext()->getParent() != 0) + return; + // Check if the value is escaping through the return. ProgramStateRef state = C.getState(); const MemRegion *V = @@ -549,6 +554,11 @@ void MacOSKeychainAPIChecker::checkDeadSymbols(SymbolReaper &SR, // TODO: Remove this after we ensure that checkDeadSymbols are always called. void MacOSKeychainAPIChecker::checkEndPath(CheckerContext &Ctx) const { ProgramStateRef state = Ctx.getState(); + + // If inside inlined call, skip it. + if (Ctx.getLocationContext()->getParent() != 0) + return; + AllocatedSetTy AS = state->get<AllocatedData>(); if (AS.isEmpty()) return; diff --git a/test/Analysis/keychainAPI.m b/test/Analysis/keychainAPI.m index 613d74659f..a98ebfdf42 100644 --- a/test/Analysis/keychainAPI.m +++ b/test/Analysis/keychainAPI.m @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -analyze -analyzer-checker=osx.SecKeychainAPI %s -verify +// RUN: %clang_cc1 -analyze -analyzer-checker=osx.SecKeychainAPI %s -analyzer-inline-call -verify // Fake typedefs. typedef unsigned int OSStatus; @@ -133,7 +133,7 @@ void* returnContent() { return outData; } // no-warning -// Password was passed in as an argument and does nt have to be deleted. +// Password was passed in as an argument and does not have to be deleted. OSStatus getPasswordAndItem(void** password, UInt32* passwordLength) { OSStatus err; SecKeychainItemRef item; @@ -337,3 +337,63 @@ static int *bug10798(int *p, int columns, int prevRow) { } while(10 >= row[1]); return row; } + +// Test inter-procedural behaviour. + +void my_FreeParam(void *attrList, void* X) { + SecKeychainItemFreeContent(attrList, X); +} + +void *my_AllocateReturn(OSStatus *st) { + unsigned int *ptr = 0; + UInt32 length; + void *outData; + *st = SecKeychainItemCopyContent(2, ptr, ptr, &length, &outData); + return outData; +} + +OSStatus my_Allocate_Param(void** password, UInt32* passwordLength) { + OSStatus err; + SecKeychainItemRef item; + err = SecKeychainFindGenericPassword(0, 3, "xx", 3, "xx", + passwordLength, password, &item); + return err; +} + +void allocAndFree1() { + unsigned int *ptr = 0; + OSStatus st = 0; + UInt32 length; + void *outData; + st = SecKeychainItemCopyContent(2, ptr, ptr, &length, &outData); + if (st == noErr) + my_FreeParam(ptr, outData); +} + +void allocNoFree2() { + OSStatus st = 0; + void *outData = my_AllocateReturn(&st); // expected-warning{{Allocated data is not released:}} +} + +void allocAndFree2(void *attrList) { + OSStatus st = 0; + void *outData = my_AllocateReturn(&st); + if (st == noErr) + my_FreeParam(attrList, outData); +} + +void allocNoFree3() { + UInt32 length = 32; + void *outData; + OSStatus st = my_Allocate_Param(&outData, &length); // expected-warning{{Allocated data is not released}} +} + +void allocAndFree3(void *attrList) { + UInt32 length = 32; + void *outData; + OSStatus st = my_Allocate_Param(&outData, &length); + if (st == noErr) + SecKeychainItemFreeContent(attrList, outData); + +} + |