]> granicus.if.org Git - clang/commitdiff
Tweak diagnostics for redeclaration of a @property in a class extension where the...
authorTed Kremenek <kremenek@apple.com>
Thu, 21 Oct 2010 18:49:42 +0000 (18:49 +0000)
committerTed Kremenek <kremenek@apple.com>
Thu, 21 Oct 2010 18:49:42 +0000 (18:49 +0000)
declaration have the 'readwrite' attribute.  This is a common case, and we can issue a more lucid diagnostic.

Fixes <rdar://problem/7629420>.

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

include/clang/Basic/DiagnosticSemaKinds.td
lib/Sema/SemaObjCProperty.cpp
test/SemaObjC/continuation-class-err.m
test/SemaObjC/duplicate-property-class-extension.m

index 17a585896b1273a995fe7a55b6216ff276783047..90d61dbaa13687ba54a974ebb884c88d22633085 100644 (file)
@@ -365,8 +365,12 @@ def warn_atomic_property_rule : Warning<
   "writable atomic property %0 cannot pair a synthesized setter/getter "
   "with a user defined setter/getter">;
 def err_use_continuation_class : Error<
-  "illegal declaration of property in continuation class %0"
-  ": attribute must be readwrite, while its primary must be readonly">;
+  "illegal redeclaration of property in continuation class %0"
+  " (attribute must be 'readwrite', while its primary must be 'readonly')">;
+def err_use_continuation_class_redeclaration_readwrite : Error<
+  "illegal redeclaration of 'readwrite' property in continuation class %0"
+  " (perhaps you intended this to be a 'readwrite' redeclaration of a "
+  "'readonly' public property?)">;
 def err_continuation_class : Error<"continuation class has no primary class">;
 def err_property_type : Error<"property cannot have array or function type %0">;
 def error_missing_property_context : Error<
index 251af224153fa31cda7e48258846fdd103c1ca70..1e7c1f85086cde259c21133eb7a4a2ba176667c3 100644 (file)
@@ -187,7 +187,16 @@ Sema::HandlePropertyInClassExtension(Scope *S, ObjCCategoryDecl *CDecl,
       PIDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_copy);
     PIDecl->setSetterName(SetterSel);
   } else {
-    Diag(AtLoc, diag::err_use_continuation_class)
+    // Tailor the diagnostics for the common case where a readwrite
+    // property is declared both in the @interface and the continuation.
+    // This is a common error where the user often intended the original
+    // declaration to be readonly.
+    unsigned diag =
+      (Attributes & ObjCDeclSpec::DQ_PR_readwrite) &&
+      (PIkind & ObjCPropertyDecl::OBJC_PR_readwrite)
+      ? diag::err_use_continuation_class_redeclaration_readwrite
+      : diag::err_use_continuation_class;
+    Diag(AtLoc, diag)
       << CCPrimary->getDeclName();
     Diag(PIDecl->getLocation(), diag::note_property_declare);
   }
index 252518239f16cd214aae649c9ee059a43519bb4d..700cf61eedb59c5efac0484f12c5fc03657f6f79 100644 (file)
@@ -12,7 +12,7 @@
 
 @interface ReadOnly ()
 @property(readwrite, copy) id object;  // expected-warning {{property attribute in continuation class does not match the primary class}}
-@property(readonly) id object1; // expected-error {{illegal declaration of property in continuation class 'ReadOnly': attribute must be}}
+@property(readonly) id object1; // expected-error {{illegal redeclaration of property in continuation class 'ReadOnly' (attribute must be 'readwrite', while its primary must be 'readonly')}}
 @property (readwrite, assign) int indentLevel; // OK. assign the the default in any case.
 @end
 
@@ -31,8 +31,8 @@
 @end
 
 @interface Bar ()
-@property (copy) id foo;       // expected-error {{illegal declaration of property in continuation class 'Bar': attribute must be}}
-@property (copy) id fee;       // expected-error {{illegal declaration of property in continuation class 'Bar': attribute must be}}
+@property (copy) id foo; // expected-error {{illegal redeclaration of property in continuation class 'Bar' (attribute must be 'readwrite', while its primary must be 'readonly')}}
+@property (copy) id fee; // expected-error {{illegal redeclaration of property in continuation class 'Bar' (attribute must be 'readwrite', while its primary must be 'readonly')}}
 @end
 
 @implementation Bar
index a84f83f81fd77ce00d94db9625f2af5b0c580ee7..e8a2389bbc0201cc0eef2930c2005e5107f60c46 100644 (file)
@@ -2,20 +2,22 @@
 
 @interface Foo 
 @property (readonly) char foo; // expected-note {{property declared here}}
+@property (readwrite) char bar; // expected-note {{property declared here}}
 @end
 
 @interface Foo ()
 @property (readwrite) char foo; // OK 
 @property (readwrite) char NewProperty; // expected-note 2 {{property declared here}} 
+@property (readwrite) char bar; // expected-error{{illegal redeclaration of 'readwrite' property in continuation class 'Foo' (perhaps you intended this to be a 'readwrite' redeclaration of a 'readonly' public property?)}}
 @end
 
 @interface Foo ()
 @property (readwrite) char foo;        //  OK again, make primary property readwrite for 2nd time!
-@property (readwrite) char NewProperty; // expected-error {{illegal declaration of property in continuation class 'Foo': attribute must be readwrite, while its primary must be readonly}}
+@property (readwrite) char NewProperty; // expected-error {{redeclaration of property in continuation class 'Foo' (attribute must be 'readwrite', while its primary must be 'readonly')}}
 @end
 
 @interface Foo ()
-@property (readonly) char foo; // expected-error {{illegal declaration of property in continuation class 'Foo': attribute must be readwrite, while its primary must be readonly}}
-@property (readwrite) char NewProperty; // expected-error {{illegal declaration of property in continuation class 'Foo': attribute must be readwrite, while its primary must be readonly}}
+@property (readonly) char foo; // expected-error {{redeclaration of property in continuation class 'Foo' (attribute must be 'readwrite', while its primary must be 'readonly')}}
+@property (readwrite) char NewProperty; // expected-error {{redeclaration of property in continuation class 'Foo' (attribute must be 'readwrite', while its primary must be 'readonly')}}
 @end