forked from OSchip/llvm-project
Fix inference of _Nullable for weak Objective-C properties.
The inference of _Nullable for weak Objective-C properties was broken in several ways: * It was back-patching the type information very late in the process of checking the attributes for an Objective-C property, which is just wrong. * It was using ad hoc checks to try to suppress the warning about missing nullability specifiers (-Wnullability-completeness), which didn't actual work in all cases (rdar://problem/22985457) * It was inferring _Nullable even outside of assumes-nonnull regions, which is wrong. Putting the inference of _Nullable for weak Objective-C properties in the same place as all of the other inference logic fixes all of these ills. llvm-svn: 249896
This commit is contained in:
parent
6ccc8ca6d9
commit
d4f2afa23c
|
@ -181,7 +181,7 @@ Decl *Sema::ActOnProperty(Scope *S, SourceLocation AtLoc,
|
|||
}
|
||||
|
||||
// Validate the attributes on the @property.
|
||||
CheckObjCPropertyAttributes(Res, AtLoc, Attributes,
|
||||
CheckObjCPropertyAttributes(Res, AtLoc, Attributes,
|
||||
(isa<ObjCInterfaceDecl>(ClassDecl) ||
|
||||
isa<ObjCProtocolDecl>(ClassDecl)));
|
||||
|
||||
|
@ -2301,13 +2301,6 @@ void Sema::CheckObjCPropertyAttributes(Decl *PDecl,
|
|||
if (*nullability == NullabilityKind::NonNull)
|
||||
Diag(Loc, diag::err_objc_property_attr_mutually_exclusive)
|
||||
<< "nonnull" << "weak";
|
||||
} else {
|
||||
PropertyTy =
|
||||
Context.getAttributedType(
|
||||
AttributedType::getNullabilityAttrKind(NullabilityKind::Nullable),
|
||||
PropertyTy, PropertyTy);
|
||||
TypeSourceInfo *TSInfo = PropertyDecl->getTypeSourceInfo();
|
||||
PropertyDecl->setType(PropertyTy, TSInfo);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3311,9 +3311,7 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
|
|||
|
||||
// Are we in an assume-nonnull region?
|
||||
bool inAssumeNonNullRegion = false;
|
||||
if (S.PP.getPragmaAssumeNonNullLoc().isValid() &&
|
||||
!state.getDeclarator().isObjCWeakProperty() &&
|
||||
!S.deduceWeakPropertyFromType(T)) {
|
||||
if (S.PP.getPragmaAssumeNonNullLoc().isValid()) {
|
||||
inAssumeNonNullRegion = true;
|
||||
// Determine which file we saw the assume-nonnull region in.
|
||||
FileID file = getNullabilityCompletenessCheckFileID(
|
||||
|
@ -3392,6 +3390,13 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
|
|||
complainAboutMissingNullability = CAMN_No;
|
||||
break;
|
||||
}
|
||||
|
||||
// Weak properties are inferred to be nullable.
|
||||
if (state.getDeclarator().isObjCWeakProperty() && inAssumeNonNullRegion) {
|
||||
inferNullability = NullabilityKind::Nullable;
|
||||
break;
|
||||
}
|
||||
|
||||
// fallthrough
|
||||
|
||||
case Declarator::FileContext:
|
||||
|
|
|
@ -56,7 +56,7 @@ __attribute__((objc_arc_weak_reference_unavailable))
|
|||
@interface I
|
||||
{
|
||||
}
|
||||
@property (weak) NSFont *font; // expected-error {{synthesizing __weak instance variable of type 'NSFont * _Nullable', which does not support weak references}}
|
||||
@property (weak) NSFont *font; // expected-error {{synthesizing __weak instance variable of type 'NSFont *', which does not support weak references}}
|
||||
@end
|
||||
|
||||
@implementation I // expected-note {{when implemented by class I}}
|
||||
|
@ -65,7 +65,7 @@ __attribute__((objc_arc_weak_reference_unavailable))
|
|||
|
||||
// rdar://13676793
|
||||
@protocol MyProtocol
|
||||
@property (weak) NSFont *font; // expected-error {{synthesizing __weak instance variable of type 'NSFont * _Nullable', which does not support weak references}}
|
||||
@property (weak) NSFont *font; // expected-error {{synthesizing __weak instance variable of type 'NSFont *', which does not support weak references}}
|
||||
@end
|
||||
|
||||
@interface I1 <MyProtocol>
|
||||
|
@ -76,7 +76,7 @@ __attribute__((objc_arc_weak_reference_unavailable))
|
|||
@end
|
||||
|
||||
@interface Super
|
||||
@property (weak) NSFont *font; // expected-error {{synthesizing __weak instance variable of type 'NSFont * _Nullable', which does not support weak references}}
|
||||
@property (weak) NSFont *font; // expected-error {{synthesizing __weak instance variable of type 'NSFont *', which does not support weak references}}
|
||||
@end
|
||||
|
||||
|
||||
|
|
|
@ -11,8 +11,16 @@ void foo (NSFoo * _Nonnull);
|
|||
@property(weak) NSFoo *property1;
|
||||
@end
|
||||
|
||||
#pragma clang assume_nonnull begin
|
||||
@interface NSBar ()
|
||||
@property(weak) NSFoo *property2;
|
||||
@end
|
||||
|
||||
#pragma clang assume_nonnull end
|
||||
|
||||
@implementation NSBar
|
||||
- (void) Meth {
|
||||
foo (self.property1); // expected-warning {{implicit conversion from nullable pointer 'NSFoo * _Nullable' to non-nullable pointer type 'NSFoo * _Nonnull'}}
|
||||
foo (self.property1); // no warning because nothing is inferred
|
||||
foo (self.property2); // expected-warning {{implicit conversion from nullable pointer 'NSFoo * _Nullable' to non-nullable pointer type 'NSFoo * _Nonnull'}}
|
||||
}
|
||||
@end
|
||||
|
|
|
@ -13,4 +13,9 @@ void g3(const
|
|||
@property (retain,nullable) SomeClass *property2;
|
||||
- (nullable SomeClass *)method1;
|
||||
- (void)method2:(nonnull SomeClass *)param;
|
||||
@property (readonly, weak) SomeClass *property3; // expected-warning{{missing a nullability type specifier}}
|
||||
@end
|
||||
|
||||
@interface SomeClass ()
|
||||
@property (readonly, weak) SomeClass *property4; // expected-warning{{missing a nullability type specifier}}
|
||||
@end
|
||||
|
|
|
@ -4,5 +4,15 @@ int *ptr; // expected-warning {{missing a nullability type specifier}}
|
|||
|
||||
extern void **blah; // expected-warning 2{{missing a nullability type specifier}}
|
||||
|
||||
__attribute__((objc_root_class))
|
||||
@interface ClassWithWeakProperties
|
||||
@property (readonly, weak) ClassWithWeakProperties *prop1;
|
||||
@property (readonly, weak, null_unspecified) ClassWithWeakProperties *prop2;
|
||||
@end
|
||||
|
||||
@interface ClassWithWeakProperties ()
|
||||
@property (readonly, weak) ClassWithWeakProperties *prop3;
|
||||
@end
|
||||
|
||||
#pragma clang assume_nonnull end
|
||||
|
||||
|
|
Loading…
Reference in New Issue