summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGeorge Karpenkov <ekarpenkov@apple.com>2019-01-18 03:12:48 +0000
committerGeorge Karpenkov <ekarpenkov@apple.com>2019-01-18 03:12:48 +0000
commita2280e0c93ce921335589335f1a9eba10fed7360 (patch)
tree0cab50e96fa4c82e4f95b4555e39c8c42312c4f0
parenta0425f3a2fe5f00f82e8792d63eb1274839d7a78 (diff)
downloadbcm5719-llvm-a2280e0c93ce921335589335f1a9eba10fed7360.tar.gz
bcm5719-llvm-a2280e0c93ce921335589335f1a9eba10fed7360.zip
[analyzer] [RetainCountChecker] Produce a correct message when OSTypeAlloc is used
Differential Revision: https://reviews.llvm.org/D56820 llvm-svn: 351509
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp28
-rw-r--r--clang/test/Analysis/os_object_base.h2
-rw-r--r--clang/test/Analysis/osobject-retain-release.cpp7
3 files changed, 35 insertions, 2 deletions
diff --git a/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp b/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
index cda1a928de1..85b97ac9c02 100644
--- a/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
@@ -132,6 +132,32 @@ static Optional<unsigned> findArgIdxOfSymbol(ProgramStateRef CurrSt,
return None;
}
+Optional<std::string> findMetaClassAlloc(const Expr *Callee) {
+ if (const auto *ME = dyn_cast<MemberExpr>(Callee)) {
+ if (ME->getMemberDecl()->getNameAsString() != "alloc")
+ return None;
+ const Expr *This = ME->getBase()->IgnoreParenImpCasts();
+ if (const auto *DRE = dyn_cast<DeclRefExpr>(This)) {
+ const ValueDecl *VD = DRE->getDecl();
+ if (VD->getNameAsString() != "metaClass")
+ return None;
+
+ if (const auto *RD = dyn_cast<CXXRecordDecl>(VD->getDeclContext()))
+ return RD->getNameAsString();
+
+ }
+ }
+ return None;
+}
+
+std::string findAllocatedObjectName(const Stmt *S,
+ QualType QT) {
+ if (const auto *CE = dyn_cast<CallExpr>(S))
+ if (auto Out = findMetaClassAlloc(CE->getCallee()))
+ return *Out;
+ return getPrettyTypeName(QT);
+}
+
static void generateDiagnosticsForCallLike(ProgramStateRef CurrSt,
const LocationContext *LCtx,
const RefVal &CurrV, SymbolRef &Sym,
@@ -189,7 +215,7 @@ static void generateDiagnosticsForCallLike(ProgramStateRef CurrSt,
os << "a Core Foundation object of type '"
<< Sym->getType().getAsString() << "' with a ";
} else if (CurrV.getObjKind() == ObjKind::OS) {
- os << "an OSObject of type '" << getPrettyTypeName(Sym->getType())
+ os << "an OSObject of type '" << findAllocatedObjectName(S, Sym->getType())
<< "' with a ";
} else if (CurrV.getObjKind() == ObjKind::Generalized) {
os << "an object of type '" << Sym->getType().getAsString()
diff --git a/clang/test/Analysis/os_object_base.h b/clang/test/Analysis/os_object_base.h
index 997d0d29588..e388dddd58f 100644
--- a/clang/test/Analysis/os_object_base.h
+++ b/clang/test/Analysis/os_object_base.h
@@ -47,7 +47,7 @@ struct OSObject : public OSMetaClassBase {
};
struct OSMetaClass : public OSMetaClassBase {
- virtual OSObject * alloc();
+ virtual OSObject * alloc() const;
virtual ~OSMetaClass(){}
};
diff --git a/clang/test/Analysis/osobject-retain-release.cpp b/clang/test/Analysis/osobject-retain-release.cpp
index af40a55aef2..3aaaab3bef0 100644
--- a/clang/test/Analysis/osobject-retain-release.cpp
+++ b/clang/test/Analysis/osobject-retain-release.cpp
@@ -627,3 +627,10 @@ void test_smart_ptr_no_leak() {
}
obj->release();
}
+
+void test_ostypealloc_correct_diagnostic_name() {
+ OSArray *arr = OSTypeAlloc(OSArray); // expected-note{{Call to method 'OSMetaClass::alloc' returns an OSObject of type 'OSArray' with a +1 retain count}}
+ arr->retain(); // expected-note{{Reference count incremented. The object now has a +2 retain count}}
+ arr->release(); // expected-note{{Reference count decremented. The object now has a +1 retain count}}
+} // expected-note{{Object leaked: object allocated and stored into 'arr' is not referenced later in this execution path and has a retain count of +1}}
+ // expected-warning@-1{{Potential leak of an object stored into 'arr'}}
OpenPOWER on IntegriCloud