From: George Karpenkov Date: Thu, 6 Dec 2018 22:07:12 +0000 (+0000) Subject: [analyzer] Rely on os_consumes_this attribute to signify that the method call consume... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=0959dfd10b99c7f435c04a526958823afc0db73a;p=clang [analyzer] Rely on os_consumes_this attribute to signify that the method call consumes a reference for "this" Differential Revision: https://reviews.llvm.org/D55158 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@348533 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h b/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h index dfcbd0c85c..c2e9eaa622 100644 --- a/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h +++ b/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h @@ -369,8 +369,12 @@ public: /// This is only meaningful if the summary applies to an ObjCMessageExpr*. ArgEffect getReceiverEffect() const { return Receiver; } + /// \return the effect on the "this" receiver of the method call. ArgEffect getThisEffect() const { return This; } + /// Set the effect of the method on "this". + void setThisEffect(ArgEffect e) { This = e; } + bool isNoop() const { return Ret == RetEffect::MakeNoRet() && Receiver == DoNothing && DefaultArgEffect == MayEscape && This == DoNothing diff --git a/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp b/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp index 0e82d9ab40..67efa542d8 100644 --- a/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp +++ b/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp @@ -759,6 +759,9 @@ RetainSummaryManager::updateSummaryFromAnnotations(const RetainSummary *&Summ, QualType RetTy = FD->getReturnType(); if (Optional RetE = getRetEffectFromAnnotations(RetTy, FD)) Template->setRetEffect(*RetE); + + if (FD->hasAttr()) + Template->setThisEffect(DecRef); } void diff --git a/test/Analysis/osobject-retain-release.cpp b/test/Analysis/osobject-retain-release.cpp index a596d0d1b6..cf92e2d678 100644 --- a/test/Analysis/osobject-retain-release.cpp +++ b/test/Analysis/osobject-retain-release.cpp @@ -5,6 +5,7 @@ struct OSMetaClass; #define OS_CONSUME __attribute__((os_consumed)) #define OS_RETURNS_RETAINED __attribute__((os_returns_retained)) #define OS_RETURNS_NOT_RETAINED __attribute__((os_returns_not_retained)) +#define OS_CONSUMES_THIS __attribute__((os_consumes_this)) #define OSTypeID(type) (type::metaClass) @@ -49,6 +50,11 @@ struct OSArray : public OSObject { virtual void consumeReference(OS_CONSUME OSArray *other); + void putIntoArray(OSArray *array) OS_CONSUMES_THIS; + + template + void putIntoT(T *owner) OS_CONSUMES_THIS; + static OSArray *generateArrayHasCode() { return new OSArray; } @@ -112,6 +118,16 @@ unsigned int check_attribute_indirect_propagation(MyArray *arr) { return 0; } +void check_consumes_this(OSArray *owner) { + OSArray *arr = new OSArray; + arr->putIntoArray(owner); +} + +void check_consumes_this_with_template(OSArray *owner) { + OSArray *arr = new OSArray; + arr->putIntoT(owner); +} + void check_free_no_error() { OSArray *arr = OSArray::withCapacity(10); arr->retain();