]> granicus.if.org Git - clang/commitdiff
[attributes] Add an attribute os_consumes_this, with similar semantics to ns_consumes...
authorGeorge Karpenkov <ekarpenkov@apple.com>
Thu, 6 Dec 2018 22:06:59 +0000 (22:06 +0000)
committerGeorge Karpenkov <ekarpenkov@apple.com>
Thu, 6 Dec 2018 22:06:59 +0000 (22:06 +0000)
The attribute specifies that the call of the C++ method consumes a
reference to "this".

Differential Revision: https://reviews.llvm.org/D55155

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@348532 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/Attr.td
include/clang/Basic/AttrDocs.td
lib/Sema/SemaDeclAttr.cpp
test/Sema/attr-osobject.cpp

index d64404041fa40f8684bb6c144a26275ae802b97a..04125e67b2805ffd340db1d74aa03b9c4c3ace8d 100644 (file)
@@ -90,6 +90,10 @@ def NonBitField : SubsetSubject<Field,
                                 [{!S->isBitField()}],
                                 "non-bit-field non-static data members">;
 
+def NonStaticCXXMethod : SubsetSubject<CXXMethod,
+                                       [{!S->isStatic()}],
+                                       "non-static member functions">;
+
 def NonStaticNonConstCXXMethod
     : SubsetSubject<CXXMethod,
                     [{!S->isStatic() && !S->isConst()}],
@@ -846,6 +850,12 @@ def OSReturnsNotRetained : InheritableAttr {
   let Documentation = [RetainBehaviorDocs];
 }
 
+def OSConsumesThis : InheritableAttr {
+  let Spellings = [Clang<"os_consumes_this">];
+  let Subjects = SubjectList<[NonStaticCXXMethod]>;
+  let Documentation = [RetainBehaviorDocs];
+}
+
 def Cleanup : InheritableAttr {
   let Spellings = [GCC<"cleanup">];
   let Args = [FunctionArgument<"FunctionDecl">];
@@ -1649,13 +1659,13 @@ def NSReturnsAutoreleased : InheritableAttr {
 def NSConsumesSelf : InheritableAttr {
   let Spellings = [Clang<"ns_consumes_self">];
   let Subjects = SubjectList<[ObjCMethod]>;
-  let Documentation = [Undocumented];
+  let Documentation = [RetainBehaviorDocs];
 }
 
 def NSConsumed : InheritableParamAttr {
   let Spellings = [Clang<"ns_consumed">];
   let Subjects = SubjectList<[ParmVar]>;
-  let Documentation = [Undocumented];
+  let Documentation = [RetainBehaviorDocs];
 }
 
 def ObjCException : InheritableAttr {
index 5c9f2b9088fd403c68434f2666f94e17bcc477ea..e72ef253f086a2092b99e3d5b88ab667bf73ecd4 100644 (file)
@@ -862,6 +862,9 @@ is responsible for freeing it.
 Similiarly, the annotation ``__attribute__((ns_returns_not_retained))``
 specifies that the object is returned at ``+0`` and the ownership remains with
 the callee.
+The annotation ``__attribute__((ns_consumes_self))`` specifies that
+the Objective-C method call consumes the reference to ``self``, e.g. by
+attaching it to a supplied parameter.
 Additionally, parameters can have an annotation
 ``__attribute__((ns_consumed))``, which specifies that passing an owned object
 as that parameter effectively transfers the ownership, and the caller is no
@@ -881,7 +884,11 @@ the same attribute family is present:
 ``__attribute__((os_returns_not_retained))``,
 ``__attribute__((os_returns_retained))`` and ``__attribute__((os_consumed))``,
 with the same respective semantics.
-These attributes are also used by the Clang Static Analyzer.
+Similar to ``__attribute__((ns_consumes_self))``,
+``__attribute__((os_consumes_this))`` specifies that the method call consumes
+the reference to "this" (e.g., when attaching it to a different object supplied
+as a parameter).
+These attributes are only used by the Clang Static Analyzer.
 
 The family of attributes ``X_returns_X_retained`` can be added to functions,
 C++ methods, and Objective-C methods and properties.
index a2520c03cb348719af5e5cf24c36aadb55d9bb79..78374b80894f562ff4490c51526fb5abd08703f3 100644 (file)
@@ -6408,6 +6408,9 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
   case ParsedAttr::AT_NSConsumesSelf:
     handleSimpleAttribute<NSConsumesSelfAttr>(S, D, AL);
     break;
+  case ParsedAttr::AT_OSConsumesThis:
+    handleSimpleAttribute<OSConsumesThisAttr>(S, D, AL);
+    break;
   case ParsedAttr::AT_NSReturnsAutoreleased:
   case ParsedAttr::AT_NSReturnsNotRetained:
   case ParsedAttr::AT_NSReturnsRetained:
index fe9ed6b912b9c5d9e9cae4a1d2e8dad628564196..8d87453d00a2a7395e621948b76f2ddf4336e24e 100644 (file)
@@ -4,6 +4,10 @@ struct S {
   __attribute__((os_returns_retained)) S* method_returns_retained() {
     return nullptr;
   }
+
+  __attribute__((os_consumes_this)) void method_consumes_this();
+
+  __attribute__((os_consumes_this)) static void rejected_on_static(); // expected-warning{{'os_consumes_this' attribute only applies to non-static member functions}}
 };
 __attribute__((os_returns_retained)) S *ret_retained() {
   return nullptr;
@@ -37,6 +41,8 @@ struct __attribute__((os_returns_retained)) NoRetainAttrOnStruct {}; // expected
 
 __attribute__((os_returns_not_retained(10))) S* os_returns_no_retained_no_extra_args( S *arg) { // expected-error{{'os_returns_not_retained' attribute takes no arguments}}
   return nullptr;
-} 
+}
 
 struct __attribute__((os_returns_not_retained)) NoNotRetainedAttrOnStruct {}; // expected-warning{{'os_returns_not_retained' attribute only applies to functions, Objective-C methods, and Objective-C properties}}
+
+__attribute__((os_consumes_this)) void no_consumes_this_on_function() {} // expected-warning{{'os_consumes_this' attribute only applies to non-static member functions}}