From 69d5624644dad6b5117f8fee8fc4b09427861367 Mon Sep 17 00:00:00 2001 From: Fariborz Jahanian Date: Thu, 22 Jul 2010 23:33:21 +0000 Subject: Warn when property ivar lookup finds a global variable of same name. In nonfragile-abi2, lookup accesses a synthesized ivar. This is a transition warning. Radar 8225011. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@109197 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Basic/DiagnosticGroups.td | 1 + include/clang/Basic/DiagnosticSemaKinds.td | 4 ++++ lib/Sema/SemaExpr.cpp | 33 ++++++++++++++++++++++++++++-- test/SemaObjC/conflict-nonfragile-abi2.m | 13 ++++++++++++ 4 files changed, 49 insertions(+), 2 deletions(-) create mode 100644 test/SemaObjC/conflict-nonfragile-abi2.m diff --git a/include/clang/Basic/DiagnosticGroups.td b/include/clang/Basic/DiagnosticGroups.td index 033b6c4214..f0c556ce3a 100644 --- a/include/clang/Basic/DiagnosticGroups.td +++ b/include/clang/Basic/DiagnosticGroups.td @@ -135,6 +135,7 @@ def ReadOnlySetterAttrs : DiagGroup<"readonly-setter-attrs">; def Reorder : DiagGroup<"reorder">; def UndeclaredSelector : DiagGroup<"undeclared-selector">; def Selector : DiagGroup<"selector">; +def NonfragileAbi2 : DiagGroup<"nonfragile-abi2">; def Protocol : DiagGroup<"protocol">; def SuperSubClassMismatch : DiagGroup<"super-class-method-mismatch">; def : DiagGroup<"variadic-macros">; diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 6fb53189cd..12933ca601 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -2492,6 +2492,10 @@ def note_condition_assign_silence : Note< def warn_value_always_zero : Warning< "%0 is always %select{zero|false|NULL}1 in this context">; +def warn_ivar_variable_conflict : Warning< + "%0 lookup will access the property ivar in nonfragile-abi2 mode">, + InGroup; + // assignment related diagnostics (also for argument passing, returning, etc). // In most of these diagnostics the %2 is a value from the // Sema::AssignmentAction enumeration diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 58bc4f0801..d2f68e0331 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -1005,6 +1005,25 @@ bool Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R, return true; } +static ObjCPropertyDecl *OkToSynthesizeProvisionalIvar(Sema &SemaRef, + IdentifierInfo *II, + SourceLocation NameLoc) { + ObjCMethodDecl *CurMeth = SemaRef.getCurMethodDecl(); + ObjCInterfaceDecl *IDecl = CurMeth->getClassInterface(); + if (!IDecl) + return 0; + ObjCImplementationDecl *ClassImpDecl = IDecl->getImplementation(); + if (!ClassImpDecl) + return 0; + ObjCPropertyDecl *property = SemaRef.LookupPropertyDecl(IDecl, II); + if (!property) + return 0; + if (ObjCPropertyImplDecl *PIDecl = ClassImpDecl->FindPropertyImplDecl(II)) + if (PIDecl->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic) + return 0; + return property; +} + static ObjCIvarDecl *SynthesizeProvisionalIvar(Sema &SemaRef, IdentifierInfo *II, SourceLocation NameLoc) { @@ -1077,7 +1096,7 @@ Sema::OwningExprResult Sema::ActOnIdExpression(Scope *S, isAddressOfOperand, TemplateArgs); } - + bool IvarLookupFollowUp = false; // Perform the required lookup. LookupResult R(*this, Name, NameLoc, LookupOrdinaryName); if (TemplateArgs) { @@ -1090,7 +1109,7 @@ Sema::OwningExprResult Sema::ActOnIdExpression(Scope *S, LookupTemplateName(R, S, SS, QualType(), /*EnteringContext=*/false, MemberOfUnknownSpecialization); } else { - bool IvarLookupFollowUp = (!SS.isSet() && II && getCurMethodDecl()); + IvarLookupFollowUp = (!SS.isSet() && II && getCurMethodDecl()); LookupParsedName(R, S, &SS, !IvarLookupFollowUp); // If this reference is in an Objective-C method, then we need to do @@ -1151,6 +1170,16 @@ Sema::OwningExprResult Sema::ActOnIdExpression(Scope *S, assert(!R.empty() || ADL); if (VarDecl *Var = R.getAsSingle()) { + if (getLangOptions().ObjCNonFragileABI && IvarLookupFollowUp && + !getLangOptions().ObjCNonFragileABI2) { + ObjCPropertyDecl *Property = + OkToSynthesizeProvisionalIvar(*this, II, NameLoc); + if (Property) { + Diag(NameLoc, diag::warn_ivar_variable_conflict) << Var->getDeclName(); + Diag(Property->getLocation(), diag::note_property_declare); + } + } + // Warn about constructs like: // if (void *X = foo()) { ... } else { X }. // In the else block, the pointer is always false. diff --git a/test/SemaObjC/conflict-nonfragile-abi2.m b/test/SemaObjC/conflict-nonfragile-abi2.m new file mode 100644 index 0000000000..49cff97ccb --- /dev/null +++ b/test/SemaObjC/conflict-nonfragile-abi2.m @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -fobjc-nonfragile-abi -verify -fsyntax-only %s +// rdar : // 8225011 + +int glob; + +@interface I +@property int glob; // expected-note {{property declared here}} +@end + +@implementation I +- (int) Meth { return glob; } // expected-warning {{'glob' lookup will access the property ivar in nonfragile-abi2 mode}} +@synthesize glob; +@end -- cgit v1.2.3-18-g5258