diff options
| author | Fariborz Jahanian <fjahanian@apple.com> | 2014-05-28 18:12:10 +0000 |
|---|---|---|
| committer | Fariborz Jahanian <fjahanian@apple.com> | 2014-05-28 18:12:10 +0000 |
| commit | 555132824a9e28993a22c1fb1933287999d5733a (patch) | |
| tree | 9dd1b7f8a5546654c1b87872a1ded788f1c16977 | |
| parent | a43e98cc741656d10643a6c70c0a9b64fa38c8a4 (diff) | |
| download | bcm5719-llvm-555132824a9e28993a22c1fb1933287999d5733a.tar.gz bcm5719-llvm-555132824a9e28993a22c1fb1933287999d5733a.zip | |
Objective-C. Diagnose use of properties in functions nested in,
now deprecated, ObjC containers instead of crashing.
// rdar://16859666
llvm-svn: 209758
| -rw-r--r-- | clang/include/clang/Basic/DiagnosticSemaKinds.td | 3 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaPseudoObject.cpp | 20 | ||||
| -rw-r--r-- | clang/test/SemaObjC/deprecate_function_containers.m | 14 |
3 files changed, 36 insertions, 1 deletions
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 86e8b3e7413..5ecdb0fe8bb 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 94b19431a3e..339fe07b8cb 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 4bee7423821..531cf11d270 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 |

