r178731 - Be sure to check ARC conventions on the implicit method declarations

John McCall rjmccall at apple.com
Wed Apr 3 18:38:37 PDT 2013


Author: rjmccall
Date: Wed Apr  3 20:38:37 2013
New Revision: 178731

URL: http://llvm.org/viewvc/llvm-project?rev=178731&view=rev
Log:
Be sure to check ARC conventions on the implicit method declarations
of a property just in case the property's getter happens to be +1.
We won't synthesize a getter for such a property, but we will allow
the user to define a +1 method for it.
rdar://13115896

Modified:
    cfe/trunk/include/clang/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaDeclObjC.cpp
    cfe/trunk/lib/Sema/SemaObjCProperty.cpp
    cfe/trunk/test/CodeGenObjC/arc-property.m

Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=178731&r1=178730&r2=178731&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Wed Apr  3 20:38:37 2013
@@ -6361,6 +6361,7 @@ public:
   ObjCMethodDecl *LookupMethodInObjectType(Selector Sel, QualType Ty,
                                            bool IsInstance);
 
+  bool CheckARCMethodDecl(ObjCMethodDecl *method);
   bool inferObjCARCLifetime(ValueDecl *decl);
 
   ExprResult

Modified: cfe/trunk/lib/Sema/SemaDeclObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclObjC.cpp?rev=178731&r1=178730&r2=178731&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclObjC.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclObjC.cpp Wed Apr  3 20:38:37 2013
@@ -193,7 +193,7 @@ void Sema::CheckObjCMethodOverride(ObjCM
 
 /// \brief Check a method declaration for compatibility with the Objective-C
 /// ARC conventions.
-static bool CheckARCMethodDecl(Sema &S, ObjCMethodDecl *method) {
+bool Sema::CheckARCMethodDecl(ObjCMethodDecl *method) {
   ObjCMethodFamily family = method->getMethodFamily();
   switch (family) {
   case OMF_None:
@@ -207,17 +207,17 @@ static bool CheckARCMethodDecl(Sema &S,
     return false;
 
   case OMF_dealloc:
-    if (!S.Context.hasSameType(method->getResultType(), S.Context.VoidTy)) {
+    if (!Context.hasSameType(method->getResultType(), Context.VoidTy)) {
       SourceRange ResultTypeRange;
       if (const TypeSourceInfo *ResultTypeInfo
           = method->getResultTypeSourceInfo())
         ResultTypeRange = ResultTypeInfo->getTypeLoc().getSourceRange();
       if (ResultTypeRange.isInvalid())
-        S.Diag(method->getLocation(), diag::error_dealloc_bad_result_type) 
+        Diag(method->getLocation(), diag::error_dealloc_bad_result_type) 
           << method->getResultType() 
           << FixItHint::CreateInsertion(method->getSelectorLoc(0), "(void)");
       else
-        S.Diag(method->getLocation(), diag::error_dealloc_bad_result_type) 
+        Diag(method->getLocation(), diag::error_dealloc_bad_result_type) 
           << method->getResultType() 
           << FixItHint::CreateReplacement(ResultTypeRange, "void");
       return true;
@@ -226,11 +226,11 @@ static bool CheckARCMethodDecl(Sema &S,
       
   case OMF_init:
     // If the method doesn't obey the init rules, don't bother annotating it.
-    if (S.checkInitMethod(method, QualType()))
+    if (checkInitMethod(method, QualType()))
       return true;
 
-    method->addAttr(new (S.Context) NSConsumesSelfAttr(SourceLocation(),
-                                                       S.Context));
+    method->addAttr(new (Context) NSConsumesSelfAttr(SourceLocation(),
+                                                     Context));
 
     // Don't add a second copy of this attribute, but otherwise don't
     // let it be suppressed.
@@ -249,8 +249,8 @@ static bool CheckARCMethodDecl(Sema &S,
     break;
   }
 
-  method->addAttr(new (S.Context) NSReturnsRetainedAttr(SourceLocation(),
-                                                        S.Context));
+  method->addAttr(new (Context) NSReturnsRetainedAttr(SourceLocation(),
+                                                      Context));
   return false;
 }
 
@@ -3032,7 +3032,7 @@ Decl *Sema::ActOnMethodDeclaration(
 
   bool ARCError = false;
   if (getLangOpts().ObjCAutoRefCount)
-    ARCError = CheckARCMethodDecl(*this, ObjCMethod);
+    ARCError = CheckARCMethodDecl(ObjCMethod);
 
   // Infer the related result type when possible.
   if (!ARCError && RTC == Sema::RTC_Compatible &&

Modified: cfe/trunk/lib/Sema/SemaObjCProperty.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaObjCProperty.cpp?rev=178731&r1=178730&r2=178731&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaObjCProperty.cpp (original)
+++ cfe/trunk/lib/Sema/SemaObjCProperty.cpp Wed Apr  3 20:38:37 2013
@@ -1936,6 +1936,9 @@ void Sema::ProcessPropertyDecl(ObjCPrope
     if (property->hasAttr<NSReturnsNotRetainedAttr>())
       GetterMethod->addAttr(
         ::new (Context) NSReturnsNotRetainedAttr(Loc, Context));
+
+    if (getLangOpts().ObjCAutoRefCount)
+      CheckARCMethodDecl(GetterMethod);
   } else
     // A user declared getter will be synthesize when @synthesize of
     // the property with the same name is seen in the @implementation
@@ -1984,6 +1987,11 @@ void Sema::ProcessPropertyDecl(ObjCPrope
       // and the real context should be the same.
       if (lexicalDC)
         SetterMethod->setLexicalDeclContext(lexicalDC);
+
+      // It's possible for the user to have set a very odd custom
+      // setter selector that causes it to have a method family.
+      if (getLangOpts().ObjCAutoRefCount)
+        CheckARCMethodDecl(SetterMethod);
     } else
       // A user declared setter will be synthesize when @synthesize of
       // the property with the same name is seen in the @implementation

Modified: cfe/trunk/test/CodeGenObjC/arc-property.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjC/arc-property.m?rev=178731&r1=178730&r2=178731&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenObjC/arc-property.m (original)
+++ cfe/trunk/test/CodeGenObjC/arc-property.m Wed Apr  3 20:38:37 2013
@@ -86,4 +86,49 @@ static Class theGlobalClass;
 // CHECK-NEXT: call void @objc_storeStrong(i8** [[T3]], i8* null) [[NUW]]
 // CHECK-NEXT: ret void
 
+// rdar://13115896
+ at interface Test3
+ at property id copyMachine;
+ at end
+
+void test3(Test3 *t) {
+  id x = t.copyMachine;
+  x = [t copyMachine];
+}
+// CHECK:    define void @test3([[TEST3:%.*]]*
+//   Prologue.
+// CHECK:      [[T:%.*]] = alloca [[TEST3]]*,
+// CHECK-NEXT: [[X:%.*]] = alloca i8*,
+//   Property access.
+// CHECK:      [[T0:%.*]] = load [[TEST3]]** [[T]],
+// CHECK-NEXT: [[SEL:%.*]] = load i8** @"\01L_OBJC_SELECTOR_REFERENCES
+// CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST3]]* [[T0]] to i8*
+// CHECK-NEXT: [[T2:%.*]] = call i8* bitcast ({{.*}} @objc_msgSend to {{.*}})(i8* [[T1]], i8* [[SEL]])
+// CHECK-NEXT: store i8* [[T2]], i8** [[X]],
+//   Message send.
+// CHECK-NEXT: [[T0:%.*]] = load [[TEST3]]** [[T]],
+// CHECK-NEXT: [[SEL:%.*]] = load i8** @"\01L_OBJC_SELECTOR_REFERENCES
+// CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST3]]* [[T0]] to i8*
+// CHECK-NEXT: [[T2:%.*]] = call i8* bitcast ({{.*}} @objc_msgSend to {{.*}})(i8* [[T1]], i8* [[SEL]])
+// CHECK-NEXT: [[T3:%.*]] = load i8** [[X]],
+// CHECK-NEXT: store i8* [[T2]], i8** [[X]],
+// CHECK-NEXT: call void @objc_release(i8* [[T3]])
+//   Epilogue.
+// CHECK-NEXT: call void @objc_storeStrong(i8** [[X]], i8* null)
+// CHECK-NEXT: [[T0:%.*]] = bitcast [[TEST3]]** [[T]] to i8**
+// CHECK-NEXT: call void @objc_storeStrong(i8** [[T0]], i8* null)
+// CHECK-NEXT: ret void
+
+ at implementation Test3
+- (id) copyMachine {
+  extern id test3_helper(void);
+  return test3_helper();
+}
+// CHECK:    define internal i8* @"\01-[Test3 copyMachine]"(
+// CHECK:      [[T0:%.*]] = call i8* @test3_helper()
+// CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T0]])
+// CHECK-NEXT: ret i8* [[T1]]
+- (void) setCopyMachine: (id) x {}
+ at end
+
 // CHECK: attributes [[NUW]] = { nounwind }





More information about the cfe-commits mailing list