diff options
| author | George Karpenkov <ekarpenkov@apple.com> | 2019-01-18 03:12:48 +0000 |
|---|---|---|
| committer | George Karpenkov <ekarpenkov@apple.com> | 2019-01-18 03:12:48 +0000 |
| commit | a2280e0c93ce921335589335f1a9eba10fed7360 (patch) | |
| tree | 0cab50e96fa4c82e4f95b4555e39c8c42312c4f0 | |
| parent | a0425f3a2fe5f00f82e8792d63eb1274839d7a78 (diff) | |
| download | bcm5719-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.cpp | 28 | ||||
| -rw-r--r-- | clang/test/Analysis/os_object_base.h | 2 | ||||
| -rw-r--r-- | clang/test/Analysis/osobject-retain-release.cpp | 7 |
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'}} |

