r191009 - ObjectiveC: Allow NS_RETURNS_INNER_POINTER annotation

jahanian fjahanian at apple.com
Thu Sep 19 10:22:22 PDT 2013


On Sep 19, 2013, at 9:46 AM, Aaron Ballman <aaron at aaronballman.com> wrote:

> On Thu, Sep 19, 2013 at 12:37 PM, Fariborz Jahanian <fjahanian at apple.com> 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
>> + at 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
>> - at 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}}
>> +}
>> + at 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

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20130919/79e0262a/attachment.html>


More information about the cfe-commits mailing list