diff options
-rw-r--r-- | include/clang/Basic/DiagnosticSemaKinds.td | 2 | ||||
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 3 | ||||
-rw-r--r-- | lib/Sema/SemaExprMember.cpp | 4 | ||||
-rw-r--r-- | test/SemaObjC/warn-direct-ivar-access.m | 33 |
4 files changed, 41 insertions, 1 deletions
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 4df26cfa55..455f3b6ec4 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -5759,6 +5759,8 @@ def ext_typecheck_base_super : Warning< def warn_missing_method_return_type : Warning< "method has no return type specified; defaults to 'id'">, InGroup<MissingMethodReturnType>, DefaultIgnore; +def warn_direct_ivar_access : Warning<"instance variable %0 is being " + "directly accessed">, InGroup<DiagGroup<"direct-ivar-access">>, DefaultIgnore; // Spell-checking diagnostics def err_unknown_type_or_class_name_suggest : Error< diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index ea121b8b3c..e8ba54d24f 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -1961,6 +1961,9 @@ Sema::LookupInObjCMethod(LookupResult &Lookup, Scope *S, return ExprError(); MarkAnyDeclReferenced(Loc, IV); + if (IV->getType()->isObjCObjectPointerType() && + getLangOpts().getGC() == LangOptions::NonGC) + Diag(Loc, diag::warn_direct_ivar_access) << IV->getDeclName(); return Owned(new (Context) ObjCIvarRefExpr(IV, IV->getType(), Loc, SelfExpr.take(), true, true)); diff --git a/lib/Sema/SemaExprMember.cpp b/lib/Sema/SemaExprMember.cpp index 79973b352f..5a116b4496 100644 --- a/lib/Sema/SemaExprMember.cpp +++ b/lib/Sema/SemaExprMember.cpp @@ -1260,7 +1260,9 @@ Sema::LookupMemberExpr(LookupResult &R, ExprResult &BaseExpr, if (DE->getType().getObjCLifetime() == Qualifiers::OCL_Weak) Diag(DE->getLocation(), diag::error_arc_weak_ivar_access); } - + if (IV->getType()->isObjCObjectPointerType() && + getLangOpts().getGC() == LangOptions::NonGC) + Diag(MemberLoc, diag::warn_direct_ivar_access) << IV->getDeclName(); return Owned(new (Context) ObjCIvarRefExpr(IV, IV->getType(), MemberLoc, BaseExpr.take(), IsArrow)); diff --git a/test/SemaObjC/warn-direct-ivar-access.m b/test/SemaObjC/warn-direct-ivar-access.m new file mode 100644 index 0000000000..6850db64a3 --- /dev/null +++ b/test/SemaObjC/warn-direct-ivar-access.m @@ -0,0 +1,33 @@ +// RUN: %clang_cc1 -fsyntax-only -Wdirect-ivar-access -verify -Wno-objc-root-class %s +// rdar://6505197 + +__attribute__((objc_root_class)) @interface MyObject { +@public + id _myMaster; + id _isTickledPink; +} +@property(retain) id myMaster; +@property(assign) id isTickledPink; +@end + +@implementation MyObject + +@synthesize myMaster = _myMaster; +@synthesize isTickledPink = _isTickledPink; + +- (void) doSomething { + _myMaster = _isTickledPink; // expected-warning {{instance variable '_myMaster' is being directly accessed}} \ + // expected-warning {{instance variable '_isTickledPink' is being directly accessed}} +} + +@end + +MyObject * foo () +{ + MyObject* p=0; + p.isTickledPink = p.myMaster; // ok + p->_isTickledPink = (*p)._myMaster; // expected-warning {{instance variable '_isTickledPink' is being directly accessed}} \ + // expected-warning {{instance variable '_myMaster' is being directly accessed}} + return p->_isTickledPink; // expected-warning {{instance variable '_isTickledPink' is being directly accessed}} +} + |