diff options
-rw-r--r-- | include/clang/Basic/DiagnosticSemaKinds.td | 3 | ||||
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 10 | ||||
-rw-r--r-- | test/SemaObjC/arc.m | 15 |
3 files changed, 28 insertions, 0 deletions
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index b608a5d694..9d35438975 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -2815,6 +2815,9 @@ def err_typecheck_member_reference_struct_union : Error< "member reference base type %0 is not a structure or union">; def err_typecheck_member_reference_ivar : Error< "%0 does not have a member named %1">; +def error_arc_weak_ivar_access : Error< + "dereferencing a __weak pointer is not allowed due to possible " + "null value caused by race condition, assign it to strong variable first">; def err_typecheck_member_reference_arrow : Error< "member reference type %0 is not a pointer">; def err_typecheck_member_reference_suggestion : Error< diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 3122d42cdb..5e30e7179c 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -4333,6 +4333,16 @@ Sema::LookupMemberExpr(LookupResult &R, ExprResult &BaseExpr, Diag(MemberLoc, diag::error_protected_ivar_access) << IV->getDeclName(); } + if (getLangOptions().ObjCAutoRefCount) { + Expr *BaseExp = BaseExpr.get()->IgnoreParenImpCasts(); + if (UnaryOperator *UO = dyn_cast<UnaryOperator>(BaseExp)) + if (UO->getOpcode() == UO_Deref) + BaseExp = UO->getSubExpr()->IgnoreParenCasts(); + + if (DeclRefExpr *DE = dyn_cast<DeclRefExpr>(BaseExp)) + if (DE->getType().getObjCLifetime() == Qualifiers::OCL_Weak) + Diag(DE->getLocation(), diag::error_arc_weak_ivar_access); + } return Owned(new (Context) ObjCIvarRefExpr(IV, IV->getType(), MemberLoc, BaseExpr.take(), diff --git a/test/SemaObjC/arc.m b/test/SemaObjC/arc.m index fa3a06183e..4c2ae236ac 100644 --- a/test/SemaObjC/arc.m +++ b/test/SemaObjC/arc.m @@ -548,3 +548,18 @@ int Test31() { int k = (pcls->isa ? i : j); // expected-error {{member reference base type 'Class<PTest31>' is not a structure or union}} return cls->isa ? i : j; // expected-error {{member reference base type 'Class' is not a structure or union}} } + +// rdar://9612030 +@interface ITest32 { +@public + id ivar; +} +@end + +id Test32(__weak ITest32 *x) { + __weak ITest32 *y; + x->ivar = 0; // expected-error {{dereferencing a __weak pointer is not allowed}} + return y ? y->ivar // expected-error {{dereferencing a __weak pointer is not allowed}} + : (*x).ivar; // expected-error {{dereferencing a __weak pointer is not allowed}} +} + |