summaryrefslogtreecommitdiffstats
path: root/clang/lib/Analysis/RetainSummaryManager.cpp
diff options
context:
space:
mode:
authorArtem Dergachev <artem.dergachev@gmail.com>2019-04-26 02:05:18 +0000
committerArtem Dergachev <artem.dergachev@gmail.com>2019-04-26 02:05:18 +0000
commit48e7a2fa8cf072749b8f7b1baa7aaa38e710b68d (patch)
tree1ff080ed2c5fa6a0afe74b36062a975cf26474e7 /clang/lib/Analysis/RetainSummaryManager.cpp
parente264ac6ae19a5dfce26582c7240df402cba269ad (diff)
downloadbcm5719-llvm-48e7a2fa8cf072749b8f7b1baa7aaa38e710b68d.tar.gz
bcm5719-llvm-48e7a2fa8cf072749b8f7b1baa7aaa38e710b68d.zip
[analyzer] RetainCount: Add a suppression for "the Matching rule".
In the OSObject universe there appears to be another slightly popular contract, apart from "create" and "get", which is "matching". It optionally consumes a "table" parameter and if a table is passed, it fills in the table and returns it at +0; otherwise, it creates a new table, fills it in and returns it at +1. For now suppress false positives by doing a conservative escape on all functions that end with "Matching", which is the naming convention that seems to be followed by all such methods. Differential Revision: https://reviews.llvm.org/D61161 llvm-svn: 359264
Diffstat (limited to 'clang/lib/Analysis/RetainSummaryManager.cpp')
-rw-r--r--clang/lib/Analysis/RetainSummaryManager.cpp35
1 files changed, 21 insertions, 14 deletions
diff --git a/clang/lib/Analysis/RetainSummaryManager.cpp b/clang/lib/Analysis/RetainSummaryManager.cpp
index ae8ccb13ca5..4f0fced60bf 100644
--- a/clang/lib/Analysis/RetainSummaryManager.cpp
+++ b/clang/lib/Analysis/RetainSummaryManager.cpp
@@ -228,29 +228,36 @@ RetainSummaryManager::isKnownSmartPointer(QualType QT) {
const RetainSummary *
RetainSummaryManager::getSummaryForOSObject(const FunctionDecl *FD,
StringRef FName, QualType RetTy) {
+ assert(TrackOSObjects &&
+ "Requesting a summary for an OSObject but OSObjects are not tracked");
+
if (RetTy->isPointerType()) {
const CXXRecordDecl *PD = RetTy->getPointeeType()->getAsCXXRecordDecl();
if (PD && isOSObjectSubclass(PD)) {
- if (const IdentifierInfo *II = FD->getIdentifier()) {
- StringRef FuncName = II->getName();
- if (isOSObjectDynamicCast(FuncName) || isOSObjectThisCast(FuncName))
- return getDefaultSummary();
-
- // All objects returned with functions *not* starting with
- // get, or iterators, are returned at +1.
- if ((!FuncName.startswith("get") && !FuncName.startswith("Get")) ||
- isOSIteratorSubclass(PD)) {
- return getOSSummaryCreateRule(FD);
- } else {
- return getOSSummaryGetRule(FD);
- }
+ if (isOSObjectDynamicCast(FName) || isOSObjectThisCast(FName))
+ return getDefaultSummary();
+
+ // TODO: Add support for the slightly common *Matching(table) idiom.
+ // Cf. IOService::nameMatching() etc. - these function have an unusual
+ // contract of returning at +0 or +1 depending on their last argument.
+ if (FName.endswith("Matching")) {
+ return getPersistentStopSummary();
+ }
+
+ // All objects returned with functions *not* starting with 'get',
+ // or iterators, are returned at +1.
+ if ((!FName.startswith("get") && !FName.startswith("Get")) ||
+ isOSIteratorSubclass(PD)) {
+ return getOSSummaryCreateRule(FD);
+ } else {
+ return getOSSummaryGetRule(FD);
}
}
}
if (const auto *MD = dyn_cast<CXXMethodDecl>(FD)) {
const CXXRecordDecl *Parent = MD->getParent();
- if (TrackOSObjects && Parent && isOSObjectSubclass(Parent)) {
+ if (Parent && isOSObjectSubclass(Parent)) {
if (FName == "release" || FName == "taggedRelease")
return getOSSummaryReleaseRule(FD);
OpenPOWER on IntegriCloud