On Sep 19, 2013, at 9:46 AM, Aaron Ballman <[email protected]> wrote:
> On Thu, Sep 19, 2013 at 12:37 PM, Fariborz Jahanian <[email protected]> > wrote: >> Author: fjahanian >> Date: Thu Sep 19 11:37:20 2013 >> New Revision: 191009 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=191009&view=rev >> Log: >> ObjectiveC: Allow NS_RETURNS_INNER_POINTER annotation >> of ObjectiveC properties to mean annotation of >> NS_RETURNS_INNER_POINTER on its synthesized getter. >> This also facilitates more migration to properties when >> methods are annotated with NS_RETURNS_INNER_POINTER. >> // rdar://14990439 >> >> Modified: >> cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td >> cfe/trunk/lib/Sema/SemaDeclAttr.cpp >> cfe/trunk/lib/Sema/SemaObjCProperty.cpp >> cfe/trunk/test/CodeGenObjC/arc-precise-lifetime.m >> cfe/trunk/test/SemaObjC/arc-property-lifetime.m >> >> Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=191009&r1=191008&r2=191009&view=diff >> ============================================================================== >> --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original) >> +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Thu Sep 19 11:37:20 >> 2013 >> @@ -2027,7 +2027,8 @@ def err_attribute_wrong_decl_type : Erro >> "variables, functions and labels|fields and global variables|structs|" >> "variables, functions and tag types|thread-local variables|" >> "variables and fields|variables, data members and tag types|" >> - "types and namespaces|Objective-C interfaces}1">; >> + "types and namespaces|Objective-C interfaces|" >> + "methods and properties}1">; >> def warn_type_attribute_wrong_type : Warning< >> "'%0' only applies to %select{function|pointer|" >> "Objective-C object or block pointer}1 types; type here is %2">, >> @@ -2395,7 +2396,7 @@ def note_attribute_overloadable_prev_ove >> def err_attribute_overloadable_no_prototype : Error< >> "'overloadable' function %0 must have a prototype">; >> def warn_ns_attribute_wrong_return_type : Warning< >> - "%0 attribute only applies to %select{functions|methods}1 that " >> + "%0 attribute only applies to %select{functions|methods|properties}1 that >> " >> "return %select{an Objective-C object|a pointer|a non-retainable >> pointer}2">, >> InGroup<IgnoredAttributes>; >> def warn_ns_attribute_wrong_parameter_type : Warning< >> >> Modified: cfe/trunk/lib/Sema/SemaDeclAttr.cpp >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=191009&r1=191008&r2=191009&view=diff >> ============================================================================== >> --- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original) >> +++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Thu Sep 19 11:37:20 2013 >> @@ -54,7 +54,8 @@ enum AttributeDeclKind { >> ExpectedVariableOrField, >> ExpectedVariableFieldOrTag, >> ExpectedTypeOrNamespace, >> - ExpectedObjectiveCInterface >> + ExpectedObjectiveCInterface, >> + ExpectedMethodOrProperty >> }; >> >> //===----------------------------------------------------------------------===// >> @@ -1476,7 +1477,7 @@ static void handleOwnershipAttr(Sema &S, >> break; >> } >> if (-1 != Err) { >> - S.Diag(AL.getLoc(), diag::err_ownership_type) << AL.getName() << Err >> + S.Diag(AL.getLoc(), diag::err_ownership_type) << AL.getName() << Err >> << Ex->getSourceRange(); >> return; >> } >> @@ -4145,29 +4146,34 @@ static void handleNSReturnsRetainedAttr( >> static void handleObjCReturnsInnerPointerAttr(Sema &S, Decl *D, >> const AttributeList &attr) { >> SourceLocation loc = attr.getLoc(); >> - >> + QualType resultType; >> + >> ObjCMethodDecl *method = dyn_cast<ObjCMethodDecl>(D); >> >> if (!method) { >> - S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type) >> - << SourceRange(loc, loc) << attr.getName() << ExpectedMethod; >> - return; >> + ObjCPropertyDecl *property = dyn_cast<ObjCPropertyDecl>(D); >> + if (!property) { >> + S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type) >> + << SourceRange(loc, loc) << attr.getName() << >> ExpectedMethodOrProperty; >> + return; >> + } >> + resultType = property->getType(); > > Please update the subjects in Attr.td for this attribute so it stays > in sync with what the semantics are checking for. > >> } >> + else >> + // Check that the method returns a normal pointer. >> + resultType = method->getResultType(); >> >> - // Check that the method returns a normal pointer. >> - QualType resultType = method->getResultType(); >> - >> if (!resultType->isReferenceType() && >> (!resultType->isPointerType() || resultType->isObjCRetainableType())) { >> - S.Diag(method->getLocStart(), diag::warn_ns_attribute_wrong_return_type) >> + S.Diag(D->getLocStart(), diag::warn_ns_attribute_wrong_return_type) >> << SourceRange(loc) >> - << attr.getName() << /*method*/ 1 << /*non-retainable pointer*/ 2; >> + << attr.getName() << (method ? /*method*/ 1 : /*property*/ 2) << >> /*non-retainable pointer*/ 2; > > A local enumeration would be better than comments, but meh. > >> >> // Drop the attribute. >> return; >> } >> >> - method->addAttr(::new (S.Context) >> + D->addAttr(::new (S.Context) >> ObjCReturnsInnerPointerAttr(attr.getRange(), S.Context, >> >> attr.getAttributeSpellingListIndex())); >> } >> >> Modified: cfe/trunk/lib/Sema/SemaObjCProperty.cpp >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaObjCProperty.cpp?rev=191009&r1=191008&r2=191009&view=diff >> ============================================================================== >> --- cfe/trunk/lib/Sema/SemaObjCProperty.cpp (original) >> +++ cfe/trunk/lib/Sema/SemaObjCProperty.cpp Thu Sep 19 11:37:20 2013 >> @@ -1943,6 +1943,10 @@ void Sema::ProcessPropertyDecl(ObjCPrope >> if (property->hasAttr<NSReturnsNotRetainedAttr>()) >> GetterMethod->addAttr( >> ::new (Context) NSReturnsNotRetainedAttr(Loc, Context)); >> + >> + if (property->hasAttr<ObjCReturnsInnerPointerAttr>()) >> + GetterMethod->addAttr( >> + ::new (Context) ObjCReturnsInnerPointerAttr(Loc, Context)); >> >> if (getLangOpts().ObjCAutoRefCount) >> CheckARCMethodDecl(GetterMethod); >> >> Modified: cfe/trunk/test/CodeGenObjC/arc-precise-lifetime.m >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjC/arc-precise-lifetime.m?rev=191009&r1=191008&r2=191009&view=diff >> ============================================================================== >> --- cfe/trunk/test/CodeGenObjC/arc-precise-lifetime.m (original) >> +++ cfe/trunk/test/CodeGenObjC/arc-precise-lifetime.m Thu Sep 19 11:37:20 >> 2013 >> @@ -25,7 +25,8 @@ void test0() { >> // rdar://problem/9821110 >> @interface Test1 >> - (char*) interior __attribute__((objc_returns_inner_pointer)); >> -// Should we allow this on properties? >> +// Should we allow this on properties? Yes! see // rdar://14990439 >> +@property (nonatomic, readonly) char * PropertyReturnsInnerPointer >> __attribute__((objc_returns_inner_pointer)); >> @end >> extern Test1 *test1_helper(void); >> >> @@ -73,6 +74,50 @@ void test1b(void) { >> char *c = [ptr interior]; >> } >> >> +void test1c(void) { >> + // CHECK: [[T0:%.*]] = call [[TEST1:%.*]]* @test1_helper() >> + // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8* >> + // CHECK-NEXT: [[T2:%.*]] = call i8* >> @objc_retainAutoreleasedReturnValue(i8* [[T1]]) >> + // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST1]]* >> + // CHECK-NEXT: store [[TEST1]]* [[T3]] >> + // CHECK-NEXT: [[T0:%.*]] = load [[TEST1]]** >> + // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8* >> + // CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retainAutorelease(i8* [[T1]]) >> + // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST1]]* >> + // CHECK-NEXT: [[T4:%.*]] = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_ >> + // CHECK-NEXT: [[T5:%.*]] = bitcast [[TEST1]]* [[T3]] to i8* >> + // CHECK-NEXT: [[T6:%.*]] = call i8* bitcast >> + // CHECK-NEXT: store i8* [[T6]], i8** >> + // CHECK-NEXT: [[T0:%.*]] = load [[TEST1]]** >> + // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8* >> + // CHECK-NEXT: call void @objc_release(i8* [[T1]]) [[NUW]], >> !clang.imprecise_release >> + // CHECK-NEXT: ret void >> + Test1 *ptr = test1_helper(); >> + char *pc = ptr.PropertyReturnsInnerPointer; >> +} >> + >> +void test1d(void) { >> + // CHECK: [[T0:%.*]] = call [[TEST1:%.*]]* @test1_helper() >> + // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8* >> + // CHECK-NEXT: [[T2:%.*]] = call i8* >> @objc_retainAutoreleasedReturnValue(i8* [[T1]]) >> + // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST1]]* >> + // CHECK-NEXT: store [[TEST1]]* [[T3]] >> + // CHECK-NEXT: [[T0:%.*]] = load [[TEST1]]** >> + // CHECK-NEXT: [[T2:%.*]] = bitcast [[TEST1]]* [[T0]] to i8* >> + // CHECK-NEXT: [[T3:%.*]] = call i8* @objc_retainAutorelease >> + // CHECK-NEXT: [[SIX:%.*]] = bitcast i8* [[T3]] to [[TEST1]]* >> + // CHECK-NEXT: [[SEVEN:%.*]] = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_ >> + // CHECK-NEXT: [[EIGHT:%.*]] = bitcast [[TEST1]]* [[SIX]] to i8* >> + // CHECK-NEXT: [[CALL1:%.*]] = call i8* bitcast (i8* (i8*, i8*, ...)* >> @objc_msgSend to i8* (i8*, i8*)*)(i8* [[EIGHT]], i8* [[SEVEN]]) >> + // CHECK-NEXT: store i8* [[CALL1]], i8** >> + // CHECK-NEXT: [[NINE:%.*]] = load [[TEST1]]** >> + // CHECK-NEXT: [[TEN:%.*]] = bitcast [[TEST1]]* [[NINE]] to i8* >> + // CHECK-NEXT: call void @objc_release(i8* [[TEN]]) >> + // CHECK-NEXT: ret void >> + __attribute__((objc_precise_lifetime)) Test1 *ptr = test1_helper(); >> + char *pc = ptr.PropertyReturnsInnerPointer; >> +} >> + >> @interface Test2 { >> @public >> id ivar; >> >> Modified: cfe/trunk/test/SemaObjC/arc-property-lifetime.m >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/arc-property-lifetime.m?rev=191009&r1=191008&r2=191009&view=diff >> ============================================================================== >> --- cfe/trunk/test/SemaObjC/arc-property-lifetime.m (original) >> +++ cfe/trunk/test/SemaObjC/arc-property-lifetime.m Thu Sep 19 11:37:20 2013 >> @@ -171,7 +171,10 @@ void foo(Baz *f) { >> >> // rdar://11253688 >> @interface Boom >> -@property (readonly) const void * innerPointer >> __attribute__((objc_returns_inner_pointer)); // expected-error >> {{'objc_returns_inner_pointer' attribute only applies to methods}} >> +{ >> + const void * innerPointerIvar >> __attribute__((objc_returns_inner_pointer)); // expected-error >> {{'objc_returns_inner_pointer' attribute only applies to methods and >> properties}} >> +} >> +@property (readonly) const void * innerPointer >> __attribute__((objc_returns_inner_pointer)); >> @end >> >> @interface Foo2 { > > Missing test cases for the changes in SemaDeclAttr.cpp; please add. Sure. In r191016. - Fariborz > > Thanks! > > ~Aaron
_______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
