diff options
author | Anna Zaks <ganna@apple.com> | 2012-05-03 23:50:33 +0000 |
---|---|---|
committer | Anna Zaks <ganna@apple.com> | 2012-05-03 23:50:33 +0000 |
commit | b79d862af66d8dd9d059863813b9a27d744bd990 (patch) | |
tree | a335fbede54f7af1b73ceca9467ef6af3989f145 /lib/StaticAnalyzer/Core/ObjCMessage.cpp | |
parent | aca0ac58d2ae80d764e3832456667d7322445e0c (diff) |
[analyzer] Assume pointer escapes when a callback is passed inside
a struct.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@156135 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/StaticAnalyzer/Core/ObjCMessage.cpp')
-rw-r--r-- | lib/StaticAnalyzer/Core/ObjCMessage.cpp | 24 |
1 files changed, 21 insertions, 3 deletions
diff --git a/lib/StaticAnalyzer/Core/ObjCMessage.cpp b/lib/StaticAnalyzer/Core/ObjCMessage.cpp index dc24e818ff..0c6d8a8b63 100644 --- a/lib/StaticAnalyzer/Core/ObjCMessage.cpp +++ b/lib/StaticAnalyzer/Core/ObjCMessage.cpp @@ -89,10 +89,28 @@ const Decl *CallOrObjCMessage::getDecl() const { } bool CallOrObjCMessage::isCallbackArg(unsigned Idx, const Type *T) const { - // Should we dig into struct fields, arrays ect? + // If the parameter is 0, it's harmless. + if (getArgSVal(Idx).isZeroConstant()) + return false; + + // If a parameter is a block or a callback, assume it can modify pointer. if (T->isBlockPointerType() || T->isFunctionPointerType()) - if (!getArgSVal(Idx).isZeroConstant()) - return true; + return true; + + // Check if a callback is passed inside a struct (for both, struct passed by + // reference and by value). Dig just one level into the struct for now. + if (const PointerType *PT = dyn_cast<PointerType>(T)) + T = PT->getPointeeType().getTypePtr(); + + if (const RecordType *RT = T->getAsStructureType()) { + const RecordDecl *RD = RT->getDecl(); + for (RecordDecl::field_iterator I = RD->field_begin(), + E = RD->field_end(); I != E; ++I ) { + const Type *FieldT = I->getType().getTypePtr(); + if (FieldT->isBlockPointerType() || FieldT->isFunctionPointerType()) + return true; + } + } return false; } |