r251384 - Be more conservative about diagnosing "incorrect" uses of __weak:

John McCall via cfe-commits cfe-commits at lists.llvm.org
Mon Oct 26 21:54:50 PDT 2015


Author: rjmccall
Date: Mon Oct 26 23:54:50 2015
New Revision: 251384

URL: http://llvm.org/viewvc/llvm-project?rev=251384&view=rev
Log:
Be more conservative about diagnosing "incorrect" uses of __weak:
allow them to be written in certain kinds of user declaration and
diagnose on the use-site instead.

Also, improve and fix some diagnostics relating to __weak and
properties.

rdar://23228631

Added:
    cfe/trunk/test/SemaObjC/mrc-no-weak.m
Modified:
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/include/clang/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaDeclAttr.cpp
    cfe/trunk/lib/Sema/SemaDeclObjC.cpp
    cfe/trunk/lib/Sema/SemaObjCProperty.cpp
    cfe/trunk/test/SemaObjC/arc-no-runtime.m
    cfe/trunk/test/SemaObjC/arc-property-decl-attrs.m
    cfe/trunk/test/SemaObjC/arc-system-header.m
    cfe/trunk/test/SemaObjC/arc-unavailable-system-function.m
    cfe/trunk/test/SemaObjC/no-gc-weak-test.m
    cfe/trunk/test/SemaObjC/synthesized-ivar.m
    cfe/trunk/test/SemaObjCXX/arc-system-header.mm

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=251384&r1=251383&r2=251384&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Mon Oct 26 23:54:50 2015
@@ -3992,6 +3992,8 @@ def err_unavailable_message : Error<"%0
 def warn_unavailable_fwdclass_message : Warning<
     "%0 may be unavailable because the receiver type is unknown">,
     InGroup<UnavailableDeclarations>;
+def note_unavailability_inferred_here : Note<
+    "unsupported declaration here">;
 def note_availability_specified_here : Note<
   "%0 has been explicitly marked "
   "%select{unavailable|deleted|deprecated|partial}1 here">;
@@ -4524,9 +4526,15 @@ let CategoryName = "ARC Semantic Issue"
 let CategoryName = "ARC Weak References" in {
 
 def err_arc_weak_no_runtime : Error<
-  "the current deployment target does not support automated __weak references">;
+  "cannot create __weak reference because the current deployment target "
+  "does not support weak references">;
 def err_arc_weak_disabled : Error<
-  "automated __weak references are disabled in manual reference counting">;
+  "cannot create __weak reference in file using manual reference counting">;
+def err_synthesizing_arc_weak_property_disabled : Error<
+  "cannot synthesize weak property in file using manual reference counting">;
+def err_synthesizing_arc_weak_property_no_runtime : Error<
+  "cannot synthesize weak property because the current deployment target "
+  "does not support weak references">;
 def warn_objc_weak_compat : Warning<
   "the meaning of __weak has changed in manual reference-counting">,
   InGroup<DiagGroup<"objc-weak-compat">>, DefaultIgnore;

Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=251384&r1=251383&r2=251384&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Mon Oct 26 23:54:50 2015
@@ -1212,16 +1212,6 @@ public:
 
   bool CheckFunctionReturnType(QualType T, SourceLocation Loc);
 
-  unsigned deduceWeakPropertyFromType(QualType T) {
-    if ((getLangOpts().getGC() != LangOptions::NonGC &&
-         T.isObjCGCWeak()) ||
-        (getLangOpts().ObjCAutoRefCount &&
-         T.getObjCLifetime() == Qualifiers::OCL_Weak))
-        return ObjCDeclSpec::DQ_PR_weak;
-    return 0;
-  }
-
-
   /// \brief Build a function type.
   ///
   /// This routine checks the function type according to C++ rules and

Modified: cfe/trunk/lib/Sema/SemaDeclAttr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=251384&r1=251383&r2=251384&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Mon Oct 26 23:54:50 2015
@@ -5332,26 +5332,53 @@ void Sema::ProcessDeclAttributes(Scope *
 }
 
 /// Is the given declaration allowed to use a forbidden type?
-static bool isForbiddenTypeAllowed(Sema &S, Decl *decl) {
+/// If so, it'll still be annotated with an attribute that makes it
+/// illegal to actually use.
+static bool isForbiddenTypeAllowed(Sema &S, Decl *decl,
+                                   const DelayedDiagnostic &diag,
+                                   llvm::StringRef &explanation) {
   // Private ivars are always okay.  Unfortunately, people don't
   // always properly make their ivars private, even in system headers.
   // Plus we need to make fields okay, too.
-  // Function declarations in sys headers will be marked unavailable.
   if (!isa<FieldDecl>(decl) && !isa<ObjCPropertyDecl>(decl) &&
       !isa<FunctionDecl>(decl))
     return false;
 
-  // Require it to be declared in a system header.
-  return S.Context.getSourceManager().isInSystemHeader(decl->getLocation());
+  // All of these declarations are allowed in all system headers. which
+  // we assume to not be defined in user code.
+  if (S.Context.getSourceManager().isInSystemHeader(decl->getLocation())) {
+    explanation = "this system declaration uses an unsupported type";
+    return true;
+  }
+
+  // We do also need to allow __weak in user declarations when it's been
+  // disabled, for ease of integration with -fno-objc-arc files, but we
+  // have to take some care against attempts to define such things.
+  // For now, that care only extends to ivars and properties.
+  if ((isa<ObjCIvarDecl>(decl) || isa<ObjCPropertyDecl>(decl))) {
+    // TODO: find a way to localize these.
+    if (diag.getForbiddenTypeDiagnostic() == diag::err_arc_weak_disabled) {
+      explanation = "cannot use weak references in file using manual "
+                    "reference counting";
+      return true;
+    }
+    if (diag.getForbiddenTypeDiagnostic() == diag::err_arc_weak_no_runtime) {
+      explanation = "cannot use weak references because the current "
+                    "deployment target does not support them";
+      return true;
+    }
+  }
+
+  return false;
 }
 
 /// Handle a delayed forbidden-type diagnostic.
 static void handleDelayedForbiddenType(Sema &S, DelayedDiagnostic &diag,
                                        Decl *decl) {
-  if (decl && isForbiddenTypeAllowed(S, decl)) {
-    decl->addAttr(UnavailableAttr::CreateImplicit(S.Context,
-                        "this system declaration uses an unsupported type",
-                        diag.Loc));
+  llvm::StringRef explanation;
+  if (decl && isForbiddenTypeAllowed(S, decl, diag, explanation)) {
+    decl->addAttr(UnavailableAttr::CreateImplicit(S.Context, explanation,
+                                                  diag.Loc));
     return;
   }
   if (S.getLangOpts().ObjCAutoRefCount)
@@ -5404,6 +5431,7 @@ static void DoEmitAvailabilityWarning(Se
                                       bool ObjCPropertyAccess) {
   // Diagnostics for deprecated or unavailable.
   unsigned diag, diag_message, diag_fwdclass_message;
+  unsigned diag_available_here = diag::note_availability_specified_here;
 
   // Matches 'diag::note_property_attribute' options.
   unsigned property_note_select;
@@ -5433,6 +5461,13 @@ static void DoEmitAvailabilityWarning(Se
     diag_fwdclass_message = diag::warn_unavailable_fwdclass_message;
     property_note_select = /* unavailable */ 1;
     available_here_select_kind = /* unavailable */ 0;
+
+    if (!Message.empty()) {
+      if (auto attr = D->getAttr<UnavailableAttr>())
+        if (attr->isImplicit())
+          diag_available_here = diag::note_unavailability_inferred_here;
+    }
+
     break;
 
   case Sema::AD_Partial:
@@ -5459,7 +5494,7 @@ static void DoEmitAvailabilityWarning(Se
     S.Diag(UnknownObjCClass->getLocation(), diag::note_forward_class);
   }
 
-  S.Diag(D->getLocation(), diag::note_availability_specified_here)
+  S.Diag(D->getLocation(), diag_available_here)
       << D << available_here_select_kind;
   if (K == Sema::AD_Partial)
     S.Diag(Loc, diag::note_partial_availability_silence) << D;

Modified: cfe/trunk/lib/Sema/SemaDeclObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclObjC.cpp?rev=251384&r1=251383&r2=251384&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclObjC.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclObjC.cpp Mon Oct 26 23:54:50 2015
@@ -3495,6 +3495,23 @@ void Sema::DiagnoseDuplicateIvars(ObjCIn
   }
 }
 
+/// Diagnose attempts to define ARC-__weak ivars when __weak is disabled.
+static void DiagnoseWeakIvars(Sema &S, ObjCImplementationDecl *ID) {
+  if (S.getLangOpts().ObjCWeak) return;
+
+  for (auto ivar = ID->getClassInterface()->all_declared_ivar_begin();
+         ivar; ivar = ivar->getNextIvar()) {
+    if (ivar->isInvalidDecl()) continue;
+    if (ivar->getType().getObjCLifetime() == Qualifiers::OCL_Weak) {
+      if (S.getLangOpts().ObjCWeakRuntime) {
+        S.Diag(ivar->getLocation(), diag::err_arc_weak_disabled);
+      } else {
+        S.Diag(ivar->getLocation(), diag::err_arc_weak_no_runtime);
+      }
+    }
+  }
+}
+
 Sema::ObjCContainerKind Sema::getObjCContainerKind() const {
   switch (CurContext->getDeclKind()) {
     case Decl::ObjCInterface:
@@ -3644,6 +3661,7 @@ Decl *Sema::ActOnAtEnd(Scope *S, SourceR
       DiagnoseUnusedBackingIvarInAccessor(S, IC);
       if (IDecl->hasDesignatedInitializers())
         DiagnoseMissingDesignatedInitOverrides(IC, IDecl);
+      DiagnoseWeakIvars(*this, IC);
 
       bool HasRootClassAttr = IDecl->hasAttr<ObjCRootClassAttr>();
       if (IDecl->getSuperClass() == nullptr) {

Modified: cfe/trunk/lib/Sema/SemaObjCProperty.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaObjCProperty.cpp?rev=251384&r1=251383&r2=251384&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaObjCProperty.cpp (original)
+++ cfe/trunk/lib/Sema/SemaObjCProperty.cpp Mon Oct 26 23:54:50 2015
@@ -61,8 +61,10 @@ static Qualifiers::ObjCLifetime getImpli
   return Qualifiers::OCL_None;
 }
 
-/// Check the internal consistency of a property declaration.
-static void checkARCPropertyDecl(Sema &S, ObjCPropertyDecl *property) {
+/// Check the internal consistency of a property declaration with
+/// an explicit ownership qualifier.
+static void checkPropertyDeclWithOwnership(Sema &S,
+                                           ObjCPropertyDecl *property) {
   if (property->isInvalidDecl()) return;
 
   ObjCPropertyDecl::PropertyAttributeKind propertyKind
@@ -70,8 +72,7 @@ static void checkARCPropertyDecl(Sema &S
   Qualifiers::ObjCLifetime propertyLifetime
     = property->getType().getObjCLifetime();
 
-  // Nothing to do if we don't have a lifetime.
-  if (propertyLifetime == Qualifiers::OCL_None) return;
+  assert(propertyLifetime != Qualifiers::OCL_None);
 
   Qualifiers::ObjCLifetime expectedLifetime
     = getImpliedARCOwnership(propertyKind, property->getType());
@@ -127,6 +128,40 @@ CheckPropertyAgainstProtocol(Sema &S, Ob
     CheckPropertyAgainstProtocol(S, Prop, P, Known);
 }
 
+static unsigned deducePropertyOwnershipFromType(Sema &S, QualType T) {
+  // In GC mode, just look for the __weak qualifier.
+  if (S.getLangOpts().getGC() != LangOptions::NonGC) {
+    if (T.isObjCGCWeak()) return ObjCDeclSpec::DQ_PR_weak;
+
+  // In ARC/MRC, look for an explicit ownership qualifier.
+  // For some reason, this only applies to __weak.
+  } else if (auto ownership = T.getObjCLifetime()) {
+    switch (ownership) {
+    case Qualifiers::OCL_Weak:
+      return ObjCDeclSpec::DQ_PR_weak;
+    case Qualifiers::OCL_Strong:
+      return ObjCDeclSpec::DQ_PR_strong;
+    case Qualifiers::OCL_ExplicitNone:
+      return ObjCDeclSpec::DQ_PR_unsafe_unretained;
+    case Qualifiers::OCL_Autoreleasing:
+    case Qualifiers::OCL_None:
+      return 0;
+    }
+    llvm_unreachable("bad qualifier");
+  }
+
+  return 0;
+}
+
+static unsigned getOwnershipRule(unsigned attr) {
+  return attr & (ObjCPropertyDecl::OBJC_PR_assign |
+                 ObjCPropertyDecl::OBJC_PR_retain |
+                 ObjCPropertyDecl::OBJC_PR_copy   |
+                 ObjCPropertyDecl::OBJC_PR_weak   |
+                 ObjCPropertyDecl::OBJC_PR_strong |
+                 ObjCPropertyDecl::OBJC_PR_unsafe_unretained);
+}
+
 Decl *Sema::ActOnProperty(Scope *S, SourceLocation AtLoc,
                           SourceLocation LParenLoc,
                           FieldDeclarator &FD,
@@ -140,19 +175,25 @@ Decl *Sema::ActOnProperty(Scope *S, Sour
   FD.D.setObjCWeakProperty((Attributes & ObjCDeclSpec::DQ_PR_weak) != 0);
   TypeSourceInfo *TSI = GetTypeForDeclarator(FD.D, S);
   QualType T = TSI->getType();
-  Attributes |= deduceWeakPropertyFromType(T);
+  if (!getOwnershipRule(Attributes)) {
+    Attributes |= deducePropertyOwnershipFromType(*this, T);
+  }
   bool isReadWrite = ((Attributes & ObjCDeclSpec::DQ_PR_readwrite) ||
                       // default is readwrite!
                       !(Attributes & ObjCDeclSpec::DQ_PR_readonly));
-  // property is defaulted to 'assign' if it is readwrite and is
-  // not retain or copy
-  bool isAssign = ((Attributes & ObjCDeclSpec::DQ_PR_assign) ||
-                   (isReadWrite &&
-                    !(Attributes & ObjCDeclSpec::DQ_PR_retain) &&
-                    !(Attributes & ObjCDeclSpec::DQ_PR_strong) &&
-                    !(Attributes & ObjCDeclSpec::DQ_PR_copy) &&
-                    !(Attributes & ObjCDeclSpec::DQ_PR_unsafe_unretained) &&
-                    !(Attributes & ObjCDeclSpec::DQ_PR_weak)));
+
+  // Property defaults to 'assign' if it is readwrite, unless this is ARC
+  // and the type is retainable.
+  bool isAssign;
+  if (Attributes & (ObjCDeclSpec::DQ_PR_assign |
+                    ObjCDeclSpec::DQ_PR_unsafe_unretained)) {
+    isAssign = true;
+  } else if (getOwnershipRule(Attributes) || !isReadWrite) {
+    isAssign = false;
+  } else {
+    isAssign = (!getLangOpts().ObjCAutoRefCount ||
+                !T->isObjCRetainableType());
+  }
 
   // Proceed with constructing the ObjCPropertyDecls.
   ObjCContainerDecl *ClassDecl = cast<ObjCContainerDecl>(CurContext);
@@ -185,8 +226,9 @@ Decl *Sema::ActOnProperty(Scope *S, Sour
                               (isa<ObjCInterfaceDecl>(ClassDecl) ||
                                isa<ObjCProtocolDecl>(ClassDecl)));
 
-  if (getLangOpts().ObjCAutoRefCount)
-    checkARCPropertyDecl(*this, Res);
+  // Check consistency if the type has explicit ownership qualification.
+  if (Res->getType().getObjCLifetime())
+    checkPropertyDeclWithOwnership(*this, Res);
 
   llvm::SmallPtrSet<ObjCProtocolDecl *, 16> KnownProtos;
   if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(ClassDecl)) {
@@ -293,15 +335,6 @@ static bool LocPropertyAttribute( ASTCon
   
 }
 
-static unsigned getOwnershipRule(unsigned attr) {
-  return attr & (ObjCPropertyDecl::OBJC_PR_assign |
-                 ObjCPropertyDecl::OBJC_PR_retain |
-                 ObjCPropertyDecl::OBJC_PR_copy   |
-                 ObjCPropertyDecl::OBJC_PR_weak   |
-                 ObjCPropertyDecl::OBJC_PR_strong |
-                 ObjCPropertyDecl::OBJC_PR_unsafe_unretained);
-}
-
 ObjCPropertyDecl *
 Sema::HandlePropertyInClassExtension(Scope *S,
                                      SourceLocation AtLoc,
@@ -425,7 +458,7 @@ Sema::HandlePropertyInClassExtension(Sco
   if (isReadWrite && (PIkind & ObjCPropertyDecl::OBJC_PR_readonly)) {
     PIkind &= ~ObjCPropertyDecl::OBJC_PR_readonly;
     PIkind |= ObjCPropertyDecl::OBJC_PR_readwrite;
-    PIkind |= deduceWeakPropertyFromType(PIDecl->getType());
+    PIkind |= deducePropertyOwnershipFromType(*this, PIDecl->getType());
     unsigned ClassExtensionMemoryModel = getOwnershipRule(Attributes);
     unsigned PrimaryClassMemoryModel = getOwnershipRule(PIkind);
     if (PrimaryClassMemoryModel && ClassExtensionMemoryModel &&
@@ -972,12 +1005,15 @@ Decl *Sema::ActOnPropertyImplDecl(Scope
       // the property type.
       } else {
         if (!getLangOpts().ObjCWeak) {
-          if (getLangOpts().ObjCWeakRuntime) {
-            Diag(PropertyDiagLoc, diag::err_arc_weak_disabled);
-          } else {
-            Diag(PropertyDiagLoc, diag::err_arc_weak_no_runtime);
+          // Only complain here when synthesizing an ivar.
+          if (!Ivar) {
+            Diag(PropertyDiagLoc,
+                 getLangOpts().ObjCWeakRuntime
+                   ? diag::err_synthesizing_arc_weak_property_disabled
+                   : diag::err_synthesizing_arc_weak_property_no_runtime);
+            Diag(property->getLocation(), diag::note_property_declare);
           }
-          Diag(property->getLocation(), diag::note_property_declare);
+          CompleteTypeErr = true; // suppress later diagnostics about the ivar
         } else {
           isARCWeak = true;
           if (const ObjCObjectPointerType *ObjT =
@@ -2201,15 +2237,6 @@ void Sema::CheckObjCPropertyAttributes(D
   
   ObjCPropertyDecl *PropertyDecl = cast<ObjCPropertyDecl>(PDecl);
   QualType PropertyTy = PropertyDecl->getType();
-  unsigned PropertyOwnership = getOwnershipRule(Attributes);
-
-  // 'readonly' property with no obvious lifetime.
-  // its life time will be determined by its backing ivar.
-  if (getLangOpts().ObjCAutoRefCount &&
-      Attributes & ObjCDeclSpec::DQ_PR_readonly &&
-      PropertyTy->isObjCRetainableType() &&
-      !PropertyOwnership)
-    return;
 
   // Check for copy or retain on non-object types.
   if ((Attributes & (ObjCDeclSpec::DQ_PR_weak | ObjCDeclSpec::DQ_PR_copy |
@@ -2319,16 +2346,14 @@ void Sema::CheckObjCPropertyAttributes(D
 
   // Warn if user supplied no assignment attribute, property is
   // readwrite, and this is an object type.
-  if (!(Attributes & (ObjCDeclSpec::DQ_PR_assign | ObjCDeclSpec::DQ_PR_copy |
-                      ObjCDeclSpec::DQ_PR_unsafe_unretained |
-                      ObjCDeclSpec::DQ_PR_retain | ObjCDeclSpec::DQ_PR_strong |
-                      ObjCDeclSpec::DQ_PR_weak)) &&
-      PropertyTy->isObjCObjectPointerType()) {
-      if (getLangOpts().ObjCAutoRefCount)
-        // With arc,  @property definitions should default to (strong) when 
-        // not specified; including when property is 'readonly'.
-        PropertyDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_strong);
-      else if (!(Attributes & ObjCDeclSpec::DQ_PR_readonly)) {
+  if (!getOwnershipRule(Attributes) && PropertyTy->isObjCRetainableType()) {
+    if (Attributes & ObjCDeclSpec::DQ_PR_readonly) {
+      // do nothing
+    } else if (getLangOpts().ObjCAutoRefCount) {
+      // With arc, @property definitions should default to strong when 
+      // not specified.
+      PropertyDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_strong);
+    } else if (PropertyTy->isObjCObjectPointerType()) {
         bool isAnyClassTy = 
           (PropertyTy->isObjCClassType() || 
            PropertyTy->isObjCQualifiedClassType());
@@ -2347,7 +2372,7 @@ void Sema::CheckObjCPropertyAttributes(D
           if (getLangOpts().getGC() == LangOptions::NonGC)
             Diag(Loc, diag::warn_objc_property_default_assign_on_object);
         }
-      }
+    }
 
     // FIXME: Implement warning dependent on NSCopying being
     // implemented. See also:

Modified: cfe/trunk/test/SemaObjC/arc-no-runtime.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/arc-no-runtime.m?rev=251384&r1=251383&r2=251384&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjC/arc-no-runtime.m (original)
+++ cfe/trunk/test/SemaObjC/arc-no-runtime.m Mon Oct 26 23:54:50 2015
@@ -2,7 +2,7 @@
 
 // rdar://problem/9150784
 void test(void) {
-  __weak id x; // expected-error {{the current deployment target does not support automated __weak references}}
+  __weak id x; // expected-error {{cannot create __weak reference because the current deployment target does not support weak references}}
   __weak void *v; // expected-warning {{'__weak' only applies to Objective-C object or block pointer types}}
 }
 
@@ -12,5 +12,5 @@ void test(void) {
 
 @implementation A
 // rdar://9605088
- at synthesize testObjectWeakProperty; // expected-error {{the current deployment target does not support automated __weak references}}
+ at synthesize testObjectWeakProperty; // expected-error {{cannot synthesize weak property because the current deployment target does not support weak references}}
 @end

Modified: cfe/trunk/test/SemaObjC/arc-property-decl-attrs.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/arc-property-decl-attrs.m?rev=251384&r1=251383&r2=251384&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjC/arc-property-decl-attrs.m (original)
+++ cfe/trunk/test/SemaObjC/arc-property-decl-attrs.m Mon Oct 26 23:54:50 2015
@@ -38,31 +38,31 @@
 
 @interface Bat 
 @property(strong) __unsafe_unretained id x; // expected-error {{strong property 'x' may not also be declared __unsafe_unretained}}
- at property(strong) __weak id y; // expected-error {{strong property 'y' may not also be declared __weak}} expected-error {{property attributes 'strong' and 'weak' are mutually exclusive}}
+ at property(strong) __weak id y; // expected-error {{strong property 'y' may not also be declared __weak}}
 @property(strong) __autoreleasing id z; // expected-error {{strong property 'z' may not also be declared __autoreleasing}}
 @end
 
 @interface Bau
 @property(retain) __unsafe_unretained id x; // expected-error {{strong property 'x' may not also be declared __unsafe_unretained}}
- at property(retain) __weak id y; // expected-error {{strong property 'y' may not also be declared __weak}} expected-error {{property attributes 'retain' and 'weak' are mutually exclusive}}
+ at property(retain) __weak id y; // expected-error {{strong property 'y' may not also be declared __weak}}
 @property(retain) __autoreleasing id z; // expected-error {{strong property 'z' may not also be declared __autoreleasing}}
 @end
 
 @interface Bav 
 @property(copy) __unsafe_unretained id x; // expected-error {{strong property 'x' may not also be declared __unsafe_unretained}}
- at property(copy) __weak id y; // expected-error {{strong property 'y' may not also be declared __weak}} expected-error {{property attributes 'copy' and 'weak' are mutually exclusive}}
+ at property(copy) __weak id y; // expected-error {{strong property 'y' may not also be declared __weak}}
 @property(copy) __autoreleasing id z; // expected-error {{strong property 'z' may not also be declared __autoreleasing}}
 @end
 
 @interface Bingo 
 @property(assign) __unsafe_unretained id x;
- at property(assign) __weak id y; // expected-error {{property attributes 'assign' and 'weak' are mutually exclusive}}
+ at property(assign) __weak id y; // expected-error {{unsafe_unretained property 'y' may not also be declared __weak}}
 @property(assign) __autoreleasing id z; // expected-error {{unsafe_unretained property 'z' may not also be declared __autoreleasing}}
 @end
 
 @interface Batman 
 @property(unsafe_unretained) __unsafe_unretained id x;
- at property(unsafe_unretained) __weak id y; // expected-error {{property attributes 'unsafe_unretained' and 'weak' are mutually exclusive}}
+ at property(unsafe_unretained) __weak id y; // expected-error {{unsafe_unretained property 'y' may not also be declared __weak}}
 @property(unsafe_unretained) __autoreleasing id z; // expected-error {{unsafe_unretained property 'z' may not also be declared __autoreleasing}}
 @end
 

Modified: cfe/trunk/test/SemaObjC/arc-system-header.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/arc-system-header.m?rev=251384&r1=251383&r2=251384&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjC/arc-system-header.m (original)
+++ cfe/trunk/test/SemaObjC/arc-system-header.m Mon Oct 26 23:54:50 2015
@@ -7,24 +7,24 @@
 void test(id op, void *cp) {
   cp = test0(op); // expected-error {{'test0' is unavailable: converts between Objective-C and C pointers in -fobjc-arc}}
   cp = *test1(&op); // expected-error {{'test1' is unavailable: converts between Objective-C and C pointers in -fobjc-arc}}
-// expected-note at arc-system-header.h:1 {{marked unavailable here}}
-// expected-note at arc-system-header.h:5 {{marked unavailable here}}
+// expected-note at arc-system-header.h:1 {{unsupported declaration here}}
+// expected-note at arc-system-header.h:5 {{unsupported declaration here}}
 }
 
 void test3(struct Test3 *p) {
   p->field = 0; // expected-error {{'field' is unavailable: this system declaration uses an unsupported type}}
-                // expected-note at arc-system-header.h:14 {{marked unavailable here}}
+                // expected-note at arc-system-header.h:14 {{unsupported declaration here}}
 }
 
 void test4(Test4 *p) {
   p->field1 = 0; // expected-error {{'field1' is unavailable: this system declaration uses an unsupported type}}
-                 // expected-note at arc-system-header.h:19 {{marked unavailable here}}
+                 // expected-note at arc-system-header.h:19 {{unsupported declaration here}}
   p->field2 = 0;
 }
 
 void test5(struct Test5 *p) {
   p->field = 0; // expected-error {{'field' is unavailable: this system field has retaining ownership}}
-                // expected-note at arc-system-header.h:25 {{marked unavailable here}}
+                // expected-note at arc-system-header.h:25 {{unsupported declaration here}}
 }
 
 id test6() {
@@ -43,7 +43,7 @@ void test7(Test7 *p) {
   p.prop = 0; // expected-error {{'prop' is unavailable: this system declaration uses an unsupported type}}
   *[p prop] = 0; // expected-error {{'prop' is unavailable: this system declaration uses an unsupported type}}
   [p setProp: 0]; // expected-error {{'setProp:' is unavailable: this system declaration uses an unsupported type}}
-// expected-note at arc-system-header.h:41 4 {{marked unavailable here}}
+// expected-note at arc-system-header.h:41 4 {{unsupported declaration here}}
 // expected-note at arc-system-header.h:41 2 {{property 'prop' is declared unavailable here}}
 }
 #endif

Modified: cfe/trunk/test/SemaObjC/arc-unavailable-system-function.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/arc-unavailable-system-function.m?rev=251384&r1=251383&r2=251384&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjC/arc-unavailable-system-function.m (original)
+++ cfe/trunk/test/SemaObjC/arc-unavailable-system-function.m Mon Oct 26 23:54:50 2015
@@ -3,7 +3,7 @@
 
 # 1 "<command line>"
 # 1 "/System/Library/Frameworks/Foundation.framework/Headers/Foundation.h" 1 3
-id * foo(); // expected-note {{'foo' has been explicitly marked unavailable here}}
+id * foo(); // expected-note {{unsupported declaration here}}
 
 # 1 "arc-unavailable-system-function.m" 2
 void ret() {

Added: cfe/trunk/test/SemaObjC/mrc-no-weak.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/mrc-no-weak.m?rev=251384&view=auto
==============================================================================
--- cfe/trunk/test/SemaObjC/mrc-no-weak.m (added)
+++ cfe/trunk/test/SemaObjC/mrc-no-weak.m Mon Oct 26 23:54:50 2015
@@ -0,0 +1,54 @@
+// RUN: %clang_cc1 -fobjc-runtime=macosx-10.8 -fsyntax-only -verify %s
+
+__attribute__((objc_root_class))
+ at interface Root @end
+
+// These should not get diagnosed immediately.
+ at interface A : Root {
+  __weak id x;
+}
+ at property __weak id y;
+ at end
+
+// Diagnostic goes on the ivar if it's explicit.
+ at interface B : Root {
+  __weak id x;  // expected-error {{cannot create __weak reference in file using manual reference counting}}
+}
+ at property __weak id x;
+ at end
+ at implementation B
+ at synthesize x;
+ at end
+
+// Otherwise, it goes with the @synthesize.
+ at interface C : Root
+ at property __weak id x; // expected-note {{property declared here}}
+ at end
+ at implementation C
+ at synthesize x; // expected-error {{cannot synthesize weak property in file using manual reference counting}}
+ at end
+
+ at interface D : Root
+ at property __weak id x; // expected-note {{property declared here}}
+ at end
+ at implementation D // expected-error {{cannot synthesize weak property in file using manual reference counting}}
+ at end
+
+ at interface E : Root {
+ at public
+  __weak id x; // expected-note 2 {{unsupported declaration here}}
+}
+ at end
+
+void testE(E *e) {
+  id x = e->x; // expected-error {{'x' is unavailable: cannot use weak references in file using manual reference counting}}
+  e->x = x; // expected-error {{'x' is unavailable: cannot use weak references in file using manual reference counting}}
+}
+
+ at interface F : Root
+ at property (weak) id x;
+ at end
+
+void testF(F *f) {
+  id x = f.x;
+}

Modified: cfe/trunk/test/SemaObjC/no-gc-weak-test.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/no-gc-weak-test.m?rev=251384&r1=251383&r2=251384&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjC/no-gc-weak-test.m (original)
+++ cfe/trunk/test/SemaObjC/no-gc-weak-test.m Mon Oct 26 23:54:50 2015
@@ -4,7 +4,7 @@
 {
   id _delegate;
 }
- at property(nonatomic,readwrite,assign)   id __weak       delegate;  // expected-error {{the current deployment target does not support automated __weak references}}
+ at property(nonatomic,readwrite,assign)   id __weak       delegate;  // expected-error {{unsafe_unretained property 'delegate' may not also be declared __weak}}
 @end
 
 @implementation Subtask
@@ -14,7 +14,7 @@
  
 @interface PVSelectionOverlayView2 
 {
- id __weak _selectionRect;  // expected-error {{the current deployment target does not support automated __weak references}} expected-error {{existing instance variable '_selectionRect' for property 'selectionRect' with assign attribute must be __unsafe_unretained}}
+ id __weak _selectionRect;  // expected-error {{cannot create __weak reference because the current deployment target does not support weak references}} expected-error {{existing instance variable '_selectionRect' for property 'selectionRect' with assign attribute must be __unsafe_unretained}}
 }
 
 @property(assign) id selectionRect; // expected-note {{property declared here}}

Modified: cfe/trunk/test/SemaObjC/synthesized-ivar.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/synthesized-ivar.m?rev=251384&r1=251383&r2=251384&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjC/synthesized-ivar.m (original)
+++ cfe/trunk/test/SemaObjC/synthesized-ivar.m Mon Oct 26 23:54:50 2015
@@ -57,5 +57,5 @@ int f0(I *a) { return a->IP; } // expect
 
 @implementation A
 // rdar://9605088
- at synthesize testObjectWeakProperty; // expected-error {{the current deployment target does not support automated __weak references}}
+ at synthesize testObjectWeakProperty; // expected-error {{cannot synthesize weak property because the current deployment target does not support weak references}}
 @end

Modified: cfe/trunk/test/SemaObjCXX/arc-system-header.mm
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjCXX/arc-system-header.mm?rev=251384&r1=251383&r2=251384&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjCXX/arc-system-header.mm (original)
+++ cfe/trunk/test/SemaObjCXX/arc-system-header.mm Mon Oct 26 23:54:50 2015
@@ -6,4 +6,4 @@ void f(A* a) {
   a->data.void_ptr = 0;
   a->data.a_b.b = 0; // expected-error{{'a_b' is unavailable: this system field has retaining ownership}}
 }
-// expected-note at arc-system-header.h:10{{'a_b' has been explicitly marked unavailable here}}
+// expected-note at arc-system-header.h:10{{unsupported declaration here}}




More information about the cfe-commits mailing list