Objective-C. Diagnose use of properties in functions nested in,
now deprecated, ObjC containers instead of crashing. // rdar://16859666 llvm-svn: 209758
This commit is contained in:
parent
a43e98cc74
commit
555132824a
|
@ -2008,6 +2008,9 @@ def note_objc_literal_comparison_isequal : Note<
|
|||
"use 'isEqual:' instead">;
|
||||
def err_attribute_argument_is_zero : Error<
|
||||
"%0 attribute must be greater than 0">;
|
||||
def err_property_function_in_objc_container : Error<
|
||||
"use of Objective-C property in function nested in Objective-C "
|
||||
"container not supported, move function outside its container">;
|
||||
|
||||
let CategoryName = "Cocoa API Issue" in {
|
||||
def warn_objc_redundant_literal_use : Warning<
|
||||
|
|
|
@ -284,6 +284,7 @@ namespace {
|
|||
bool tryBuildGetOfReference(Expr *op, ExprResult &result);
|
||||
bool findSetter(bool warn=true);
|
||||
bool findGetter();
|
||||
bool DiagnoseUnsupportedPropertyUse();
|
||||
|
||||
Expr *rebuildAndCaptureObject(Expr *syntacticBase) override;
|
||||
ExprResult buildGet() override;
|
||||
|
@ -643,6 +644,20 @@ bool ObjCPropertyOpBuilder::findSetter(bool warn) {
|
|||
return false;
|
||||
}
|
||||
|
||||
bool ObjCPropertyOpBuilder::DiagnoseUnsupportedPropertyUse() {
|
||||
if (S.getCurLexicalContext()->isObjCContainer() &&
|
||||
S.getCurLexicalContext()->getDeclKind() != Decl::ObjCCategoryImpl &&
|
||||
S.getCurLexicalContext()->getDeclKind() != Decl::ObjCImplementation) {
|
||||
if (ObjCPropertyDecl *prop = RefExpr->getExplicitProperty()) {
|
||||
S.Diag(RefExpr->getLocation(),
|
||||
diag::err_property_function_in_objc_container);
|
||||
S.Diag(prop->getLocation(), diag::note_property_declare);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Capture the base object of an Objective-C property expression.
|
||||
Expr *ObjCPropertyOpBuilder::rebuildAndCaptureObject(Expr *syntacticBase) {
|
||||
assert(InstanceReceiver == nullptr);
|
||||
|
@ -666,6 +681,9 @@ Expr *ObjCPropertyOpBuilder::rebuildAndCaptureObject(Expr *syntacticBase) {
|
|||
/// Load from an Objective-C property reference.
|
||||
ExprResult ObjCPropertyOpBuilder::buildGet() {
|
||||
findGetter();
|
||||
if (!Getter && DiagnoseUnsupportedPropertyUse())
|
||||
return ExprError();
|
||||
|
||||
assert(Getter);
|
||||
|
||||
if (SyntacticRefExpr)
|
||||
|
@ -704,6 +722,8 @@ ExprResult ObjCPropertyOpBuilder::buildGet() {
|
|||
ExprResult ObjCPropertyOpBuilder::buildSet(Expr *op, SourceLocation opcLoc,
|
||||
bool captureSetValueAsResult) {
|
||||
bool hasSetter = findSetter(false);
|
||||
if (!hasSetter && DiagnoseUnsupportedPropertyUse())
|
||||
return ExprError();
|
||||
assert(hasSetter); (void) hasSetter;
|
||||
|
||||
if (SyntacticRefExpr)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s
|
||||
// RUN: %clang_cc1 -fsyntax-only -fblocks -verify -Wno-objc-root-class %s
|
||||
// rdar://10414277
|
||||
|
||||
@protocol P
|
||||
|
@ -23,3 +23,15 @@ inline void v_imp_foo() {}
|
|||
@implementation I(CAT)
|
||||
void cat_imp_foo() {}
|
||||
@end
|
||||
|
||||
// rdar://16859666
|
||||
@interface PrototypeState
|
||||
|
||||
@property (strong, readwrite) id moin1; // expected-note {{property declared here}}
|
||||
|
||||
static inline void prototype_observe_moin1(void (^callback)(id)) { // expected-warning {{function definition inside an Objective-C container is deprecated}}
|
||||
(void)^(PrototypeState *prototypeState){
|
||||
callback(prototypeState.moin1); // expected-error {{use of Objective-C property in function nested in Objective-C container not supported, move function outside its container}}
|
||||
};
|
||||
}
|
||||
@end
|
||||
|
|
Loading…
Reference in New Issue