[cfe-commits] r144572 - in /cfe/trunk: docs/AutomaticReferenceCounting.html include/clang/Basic/DiagnosticSemaKinds.td lib/AST/DeclObjC.cpp lib/Sema/SemaExpr.cpp

Ted Kremenek kremenek at apple.com
Mon Nov 14 13:59:25 PST 2011


Author: kremenek
Date: Mon Nov 14 15:59:25 2011
New Revision: 144572

URL: http://llvm.org/viewvc/llvm-project?rev=144572&view=rev
Log:
ARC: make assignment to 'self' within class methods illegal.  Fixes <rdar://problem/10416568>.

Modified:
    cfe/trunk/docs/AutomaticReferenceCounting.html
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/lib/AST/DeclObjC.cpp
    cfe/trunk/lib/Sema/SemaExpr.cpp

Modified: cfe/trunk/docs/AutomaticReferenceCounting.html
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/AutomaticReferenceCounting.html?rev=144572&r1=144571&r2=144572&view=diff
==============================================================================
--- cfe/trunk/docs/AutomaticReferenceCounting.html (original)
+++ cfe/trunk/docs/AutomaticReferenceCounting.html Mon Nov 14 15:59:25 2011
@@ -1482,9 +1482,12 @@
 <p>The <tt>self</tt> parameter variable of an Objective-C method is
 never actually retained by the implementation.  It is undefined
 behavior, or at least dangerous, to cause an object to be deallocated
-during a message send to that object.  To make this
-safe, <tt>self</tt> is implicitly <tt>const</tt> unless the method is
-in the <a href="#family.semantics.init"><tt>init</tt> family</a>.</p>
+during a message send to that object.</p>
+
+<p>To make this safe, for Objective-C instance methods <tt>self</tt> is
+implicitly <tt>const</tt> unless the method is in the <a
+href="#family.semantics.init"><tt>init</tt> family</a>. Further, <tt>self</tt>
+is <b>always</b> implicitly <tt>const</tt> within a class method.</p>
 
 <div class="rationale"><p>Rationale: the cost of
 retaining <tt>self</tt> in all methods was found to be prohibitive, as

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=144572&r1=144571&r2=144572&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Mon Nov 14 15:59:25 2011
@@ -3078,8 +3078,10 @@
   "declaration in interface is not in the '%select{alloc|copy|init|new}0' "
   "family because %select{its result type is not an object pointer|"
   "its result type is unrelated to its receiver type}1">;
-def err_typecheck_arr_assign_self : Error<
+def err_typecheck_arc_assign_self : Error<
   "cannot assign to 'self' outside of a method in the init family">;
+def err_typecheck_arc_assign_self_class_method : Error<
+  "cannot assign to 'self' in a class method">;
 def err_typecheck_arr_assign_enumeration : Error<
   "fast enumeration variables can't be modified in ARC by default; "
   "declare the variable __strong to allow this">;

Modified: cfe/trunk/lib/AST/DeclObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclObjC.cpp?rev=144572&r1=144571&r2=144572&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclObjC.cpp (original)
+++ cfe/trunk/lib/AST/DeclObjC.cpp Mon Nov 14 15:59:25 2011
@@ -580,17 +580,26 @@
 
   bool selfIsPseudoStrong = false;
   bool selfIsConsumed = false;
-  if (isInstanceMethod() && Context.getLangOptions().ObjCAutoRefCount) {
-    selfIsConsumed = hasAttr<NSConsumesSelfAttr>();
-
-    // 'self' is always __strong.  It's actually pseudo-strong except
-    // in init methods (or methods labeled ns_consumes_self), though.
-    Qualifiers qs;
-    qs.setObjCLifetime(Qualifiers::OCL_Strong);
-    selfTy = Context.getQualifiedType(selfTy, qs);
-
-    // In addition, 'self' is const unless this is an init method.
-    if (getMethodFamily() != OMF_init && !selfIsConsumed) {
+  
+  if (Context.getLangOptions().ObjCAutoRefCount) {
+    if (isInstanceMethod()) {
+      selfIsConsumed = hasAttr<NSConsumesSelfAttr>();
+
+      // 'self' is always __strong.  It's actually pseudo-strong except
+      // in init methods (or methods labeled ns_consumes_self), though.
+      Qualifiers qs;
+      qs.setObjCLifetime(Qualifiers::OCL_Strong);
+      selfTy = Context.getQualifiedType(selfTy, qs);
+
+      // In addition, 'self' is const unless this is an init method.
+      if (getMethodFamily() != OMF_init && !selfIsConsumed) {
+        selfTy = selfTy.withConst();
+        selfIsPseudoStrong = true;
+      }
+    }
+    else {
+      assert(isClassMethod());
+      // 'self' is always const in class methods.
       selfTy = selfTy.withConst();
       selfIsPseudoStrong = true;
     }

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=144572&r1=144571&r2=144572&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Mon Nov 14 15:59:25 2011
@@ -7063,7 +7063,9 @@
           //  - self
           ObjCMethodDecl *method = S.getCurMethodDecl();
           if (method && var == method->getSelfDecl())
-            Diag = diag::err_typecheck_arr_assign_self;
+            Diag = method->isClassMethod()
+              ? diag::err_typecheck_arc_assign_self_class_method
+              : diag::err_typecheck_arc_assign_self;
 
           //  - fast enumeration variables
           else





More information about the cfe-commits mailing list