[ObjC] The absence of ownership qualifiers on an ambiguous property leads

to synthesis of a valid property even when the selected protocol property
has ownership qualifiers

rdar://39024725


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@331409 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Alex Lorenz 2018-05-02 22:40:19 +00:00
parent 262d2570eb
commit e1376f9001
2 changed files with 49 additions and 4 deletions

View File

@ -897,14 +897,24 @@ SelectPropertyForSynthesisFromProtocols(Sema &S, SourceLocation AtLoc,
: HasUnexpectedAttribute;
Mismatches.push_back({Prop, Kind, AttributeName});
};
if (isIncompatiblePropertyAttribute(OriginalAttributes, Attr,
// The ownership might be incompatible unless the property has no explicit
// ownership.
bool HasOwnership = (Attr & (ObjCPropertyDecl::OBJC_PR_retain |
ObjCPropertyDecl::OBJC_PR_strong |
ObjCPropertyDecl::OBJC_PR_copy |
ObjCPropertyDecl::OBJC_PR_assign |
ObjCPropertyDecl::OBJC_PR_unsafe_unretained |
ObjCPropertyDecl::OBJC_PR_weak)) != 0;
if (HasOwnership &&
isIncompatiblePropertyAttribute(OriginalAttributes, Attr,
ObjCPropertyDecl::OBJC_PR_copy)) {
Diag(OriginalAttributes & ObjCPropertyDecl::OBJC_PR_copy, "copy");
continue;
}
if (areIncompatiblePropertyAttributes(
OriginalAttributes, Attr, ObjCPropertyDecl::OBJC_PR_retain |
ObjCPropertyDecl::OBJC_PR_strong)) {
if (HasOwnership && areIncompatiblePropertyAttributes(
OriginalAttributes, Attr,
ObjCPropertyDecl::OBJC_PR_retain |
ObjCPropertyDecl::OBJC_PR_strong)) {
Diag(OriginalAttributes & (ObjCPropertyDecl::OBJC_PR_retain |
ObjCPropertyDecl::OBJC_PR_strong),
"retain (or strong)");

View File

@ -252,3 +252,38 @@ __attribute__((objc_root_class))
@synthesize prop = _prop;
@end
// rdar://39024725
// Allow strong readwrite property and a readonly one.
@protocol StrongCollision
@property(strong) NSObject *p;
@property(copy) NSObject *p2;
// expected-error@+1 {{property with attribute 'retain (or strong)' was selected for synthesis}}
@property(strong, readwrite) NSObject *collision;
@end
@protocol ReadonlyCollision
@property(readonly) NSObject *p;
@property(readonly) NSObject *p2;
// expected-note@+1 {{it could also be property without attribute 'retain (or strong)' declared here}}
@property(readonly, weak) NSObject *collision;
@end
@interface StrongReadonlyCollision : NSObject <StrongCollision, ReadonlyCollision>
@end
@implementation StrongReadonlyCollision
// no error
@synthesize p = _p;
@synthesize p2 = _p2;
@synthesize collision = _collision; // expected-note {{property synthesized here}}
@end