diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 86e8b3e74136..5ecdb0fe8bb8 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -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< diff --git a/clang/lib/Sema/SemaPseudoObject.cpp b/clang/lib/Sema/SemaPseudoObject.cpp index 94b19431a3ef..339fe07b8cb0 100644 --- a/clang/lib/Sema/SemaPseudoObject.cpp +++ b/clang/lib/Sema/SemaPseudoObject.cpp @@ -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) diff --git a/clang/test/SemaObjC/deprecate_function_containers.m b/clang/test/SemaObjC/deprecate_function_containers.m index 4bee74238213..531cf11d2704 100644 --- a/clang/test/SemaObjC/deprecate_function_containers.m +++ b/clang/test/SemaObjC/deprecate_function_containers.m @@ -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