From: Fariborz Jahanian Date: Wed, 6 Jul 2011 19:24:05 +0000 (+0000) Subject: objc-arc: Support objc_arc_weak_unavailable on those X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=742352a3984aeef9ecf911be23e673e97b34595f;p=clang objc-arc: Support objc_arc_weak_unavailable on those classes which are incompatible with weak references. // rdar://9693477 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@134522 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Basic/Attr.td b/include/clang/Basic/Attr.td index dea67ab9f3..e64dc6a2ad 100644 --- a/include/clang/Basic/Attr.td +++ b/include/clang/Basic/Attr.td @@ -484,6 +484,10 @@ def Unavailable : InheritableAttr { let Args = [StringArgument<"Message">]; } +def ArcWeakrefUnavailable : InheritableAttr { + let Spellings = ["objc_arc_weak_reference_unavailable"]; +} + def Unused : InheritableAttr { let Spellings = ["unused"]; } diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index c5039ff9b9..b2301e18d7 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -357,6 +357,8 @@ def err_class_extension_after_impl : Error< "cannot declare class extension for %0 after class implementation">; def note_implementation_declared : Note< "class implementation is declared here">; +def note_class_declared : Note< + "class is declared here">; def warn_dup_category_def : Warning< "duplicate definition of category %1 on interface %0">; def err_conflicting_super_class : Error<"conflicting super class name %0">; @@ -2568,6 +2570,8 @@ let CategoryName = "Automatic Reference Counting Issue" in { // ARC-mode diagnostics. def err_arc_weak_no_runtime : Error< "the current deployment target does not support automated __weak references">; +def err_arc_unsupported_weak_class : Error< + "class is incompatible with __weak references">; def err_arc_illegal_explicit_message : Error< "ARC forbids explicit message send of %0">; def err_arc_unused_init_message : Error< diff --git a/include/clang/Sema/AttributeList.h b/include/clang/Sema/AttributeList.h index d34d7f584c..4e6a0dfd4b 100644 --- a/include/clang/Sema/AttributeList.h +++ b/include/clang/Sema/AttributeList.h @@ -243,6 +243,7 @@ public: AT_weak, AT_weak_import, AT_weakref, + AT_arc_weakref_unavailable, IgnoredAttribute, UnknownAttribute }; diff --git a/lib/Sema/AttributeList.cpp b/lib/Sema/AttributeList.cpp index afc23e9be2..5a8330bbfd 100644 --- a/lib/Sema/AttributeList.cpp +++ b/lib/Sema/AttributeList.cpp @@ -107,6 +107,7 @@ AttributeList::Kind AttributeList::getKind(const IdentifierInfo *Name) { return llvm::StringSwitch(AttrName) .Case("weak", AT_weak) .Case("weakref", AT_weakref) + .Case("objc_arc_weak_reference_unavailable", AT_arc_weakref_unavailable) .Case("pure", AT_pure) .Case("mode", AT_mode) .Case("used", AT_used) diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp index 103976bc12..adef528b0a 100644 --- a/lib/Sema/SemaDeclAttr.cpp +++ b/lib/Sema/SemaDeclAttr.cpp @@ -1091,6 +1091,18 @@ static void handleUnavailableAttr(Sema &S, Decl *D, const AttributeList &Attr) { D->addAttr(::new (S.Context) UnavailableAttr(Attr.getLoc(), S.Context, Str)); } +static void handleArcWeakrefUnavailableAttr(Sema &S, Decl *D, + const AttributeList &Attr) { + unsigned NumArgs = Attr.getNumArgs(); + if (NumArgs > 0) { + S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 0; + return; + } + + D->addAttr(::new (S.Context) ArcWeakrefUnavailableAttr( + Attr.getLoc(), S.Context)); +} + static void handleAvailabilityAttr(Sema &S, Decl *D, const AttributeList &Attr) { IdentifierInfo *Platform = Attr.getParameterName(); @@ -3011,6 +3023,9 @@ static void ProcessInheritableDeclAttr(Sema &S, Scope *scope, Decl *D, case AttributeList::AT_MsStruct: handleMsStructAttr (S, D, Attr); break; case AttributeList::AT_section: handleSectionAttr (S, D, Attr); break; case AttributeList::AT_unavailable: handleUnavailableAttr (S, D, Attr); break; + case AttributeList::AT_arc_weakref_unavailable: + handleArcWeakrefUnavailableAttr (S, D, Attr); + break; case AttributeList::AT_unused: handleUnusedAttr (S, D, Attr); break; case AttributeList::AT_used: handleUsedAttr (S, D, Attr); break; case AttributeList::AT_visibility: handleVisibilityAttr (S, D, Attr); break; diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp index 1418422006..ae1ccf9886 100644 --- a/lib/Sema/SemaType.cpp +++ b/lib/Sema/SemaType.cpp @@ -3207,7 +3207,30 @@ static bool handleObjCOwnershipTypeAttr(TypeProcessingState &state, attr.setInvalid(); return true; } - + + // Forbid __weak for class objects marked as + // objc_arc_weak_reference_unavailable + if (lifetime == Qualifiers::OCL_Weak) { + QualType T = type; + if (T->isReferenceType()) { + T = T->getAs()->getPointeeType(); + } + while (const PointerType *ptr = T->getAs()) + T = ptr->getPointeeType(); + if (const ObjCObjectPointerType *ObjT = T->getAs()) { + ObjCInterfaceDecl *Class = ObjT->getInterfaceDecl(); + while (Class) { + if (Class->hasAttr()) { + S.Diag(attr.getLoc(), diag::err_arc_unsupported_weak_class); + S.Diag(ObjT->getInterfaceDecl()->getLocation(), + diag::note_class_declared); + break; + } + Class = Class->getSuperClass(); + } + } + } + return true; } diff --git a/test/SemaObjC/arc-unavailable-for-weakref.m b/test/SemaObjC/arc-unavailable-for-weakref.m new file mode 100644 index 0000000000..07a7e7b975 --- /dev/null +++ b/test/SemaObjC/arc-unavailable-for-weakref.m @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fobjc-nonfragile-abi -fobjc-runtime-has-weak -fsyntax-only -fobjc-arc -verify %s +// rdar://9693477 + +__attribute__((objc_arc_weak_reference_unavailable)) +@interface NSOptOut1072 // expected-note {{class is declared here}} +@end + +@interface sub : NSOptOut1072 @end // expected-note 2 {{class is declared here}} + +int main() { + __weak sub *w2; // expected-error {{class is incompatible with __weak references}} + + __weak NSOptOut1072 *ns1; // expected-error {{class is incompatible with __weak references}} + + id obj; + + ns1 = (__weak sub *)obj; // expected-error {{class is incompatible with __weak references}} +}