From: Fariborz Jahanian Date: Tue, 12 Jul 2011 17:16:56 +0000 (+0000) Subject: Fix a bug where a local variable named 'self' is causing X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=98a5403ecf1d2b60ae8cbf43e54194bd762cacaa;p=clang Fix a bug where a local variable named 'self' is causing implicit ivar accesses to go through the 'self' variable rather than the real 'self' for the method. // rdar://9730771 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@134992 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Sema/DeclSpec.h b/include/clang/Sema/DeclSpec.h index e3bc5bff57..cbf47e8b05 100644 --- a/include/clang/Sema/DeclSpec.h +++ b/include/clang/Sema/DeclSpec.h @@ -767,7 +767,9 @@ public: /// \brief A destructor name. IK_DestructorName, /// \brief A template-id, e.g., f. - IK_TemplateId + IK_TemplateId, + /// \brief An implicit 'self' parameter + IK_ImplicitSelfParam } Kind; /// \brief Anonymous union that holds extra data associated with the @@ -820,7 +822,7 @@ public: SourceLocation EndLocation; UnqualifiedId() : Kind(IK_Identifier), Identifier(0) { } - + /// \brief Do not use this copy constructor. It is temporary, and only /// exists because we are holding FieldDeclarators in a SmallVector when we /// don't actually need them. @@ -847,6 +849,7 @@ public: /// \brief Determine what kind of name we have. IdKind getKind() const { return Kind; } + void setKind(IdKind kind) { Kind = kind; } /// \brief Specify that this unqualified-id was parsed as an identifier. /// diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index 54debed697..263c1bd49a 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -1605,6 +1605,8 @@ public: LookupRedeclarationWithLinkage, /// Look up the name of an Objective-C protocol. LookupObjCProtocolName, + /// Look up implicit 'self' parameter of an objective-c method. + LookupObjCImplicitSelfParam, /// \brief Look up any declaration with any name. LookupAnyName }; diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 49c3f8a48f..c5caae279c 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -2766,6 +2766,7 @@ Sema::GetNameFromUnqualifiedId(const UnqualifiedId &Name) { switch (Name.getKind()) { + case UnqualifiedId::IK_ImplicitSelfParam: case UnqualifiedId::IK_Identifier: NameInfo.setName(Name.Identifier); NameInfo.setLoc(Name.StartLocation); diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index e20ec40b6a..62c163435c 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -4987,6 +4987,7 @@ Decl *Sema::ActOnUsingDeclaration(Scope *S, assert(S->getFlags() & Scope::DeclScope && "Invalid Scope."); switch (Name.getKind()) { + case UnqualifiedId::IK_ImplicitSelfParam: case UnqualifiedId::IK_Identifier: case UnqualifiedId::IK_OperatorFunctionId: case UnqualifiedId::IK_LiteralOperatorId: diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 9f91052e4c..fa8721ce34 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -1603,7 +1603,9 @@ ExprResult Sema::ActOnIdExpression(Scope *S, bool IvarLookupFollowUp = false; // Perform the required lookup. - LookupResult R(*this, NameInfo, LookupOrdinaryName); + LookupResult R(*this, NameInfo, + (Id.getKind() == UnqualifiedId::IK_ImplicitSelfParam) + ? LookupObjCImplicitSelfParam : LookupOrdinaryName); if (TemplateArgs) { // Lookup the template name again to correctly establish the context in // which it was found. This is really unfortunate as we already did the @@ -1834,6 +1836,7 @@ Sema::LookupInObjCMethod(LookupResult &Lookup, Scope *S, IdentifierInfo &II = Context.Idents.get("self"); UnqualifiedId SelfName; SelfName.setIdentifier(&II, SourceLocation()); + SelfName.setKind(UnqualifiedId::IK_ImplicitSelfParam); CXXScopeSpec SelfScopeSpec; ExprResult SelfExpr = ActOnIdExpression(S, SelfScopeSpec, SelfName, false, false); @@ -1845,27 +1848,6 @@ Sema::LookupInObjCMethod(LookupResult &Lookup, Scope *S, return ExprError(); MarkDeclarationReferenced(Loc, IV); - Expr *base = SelfExpr.take(); - base = base->IgnoreParenImpCasts(); - if (const DeclRefExpr *DE = dyn_cast(base)) { - const NamedDecl *ND = DE->getDecl(); - if (!isa(ND)) { - // relax the rule such that it is allowed to have a shadow 'self' - // where stand-alone ivar can be found in this 'self' object. - // This is to match gcc's behavior. - ObjCInterfaceDecl *selfIFace = 0; - if (const ObjCObjectPointerType *OPT = - base->getType()->getAsObjCInterfacePointerType()) - selfIFace = OPT->getInterfaceDecl(); - if (!selfIFace || - !selfIFace->lookupInstanceVariable(IV->getIdentifier())) { - Diag(Loc, diag::error_implicit_ivar_access) - << IV->getDeclName(); - Diag(ND->getLocation(), diag::note_declared_at); - return ExprError(); - } - } - } return Owned(new (Context) ObjCIvarRefExpr(IV, IV->getType(), Loc, SelfExpr.take(), true, true)); diff --git a/lib/Sema/SemaLookup.cpp b/lib/Sema/SemaLookup.cpp index 7d075db0c4..0e448e3120 100644 --- a/lib/Sema/SemaLookup.cpp +++ b/lib/Sema/SemaLookup.cpp @@ -209,6 +209,7 @@ static inline unsigned getIDNS(Sema::LookupNameKind NameKind, bool Redeclaration) { unsigned IDNS = 0; switch (NameKind) { + case Sema::LookupObjCImplicitSelfParam: case Sema::LookupOrdinaryName: case Sema::LookupRedeclarationWithLinkage: IDNS = Decl::IDNS_Ordinary; @@ -1097,7 +1098,10 @@ bool Sema::LookupName(LookupResult &R, Scope *S, bool AllowBuiltinCreation) { if (LeftStartingScope && !((*I)->hasLinkage())) continue; } - + else if (NameKind == LookupObjCImplicitSelfParam && + !isa(*I)) + continue; + R.addDecl(*I); if ((*I)->getAttr()) { @@ -1381,6 +1385,7 @@ bool Sema::LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx, // Look for this member in our base classes CXXRecordDecl::BaseMatchesCallback *BaseCallback = 0; switch (R.getLookupKind()) { + case LookupObjCImplicitSelfParam: case LookupOrdinaryName: case LookupMemberName: case LookupRedeclarationWithLinkage: diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp index 5c70c7edde..a9b416b349 100644 --- a/lib/Sema/SemaType.cpp +++ b/lib/Sema/SemaType.cpp @@ -1701,6 +1701,7 @@ static QualType GetDeclSpecTypeForDeclarator(TypeProcessingState &state, TagDecl *OwnedTagDecl = 0; switch (D.getName().getKind()) { + case UnqualifiedId::IK_ImplicitSelfParam: case UnqualifiedId::IK_OperatorFunctionId: case UnqualifiedId::IK_Identifier: case UnqualifiedId::IK_LiteralOperatorId: diff --git a/test/SemaObjC/self-declared-in-block.m b/test/SemaObjC/self-declared-in-block.m index 4bd7202144..21310953c2 100644 --- a/test/SemaObjC/self-declared-in-block.m +++ b/test/SemaObjC/self-declared-in-block.m @@ -7,11 +7,12 @@ @implementation Blocky { int _a; } -- (void)doAThing { +- (int)doAThing { ^{ - char self; // expected-note {{declared here}} - _a; // expected-error {{instance variable '_a' cannot be accessed because 'self' has been redeclared}} + char self; + return _a; }(); + return _a; } @end @@ -37,14 +38,14 @@ (void)_anIvar; } { - C* self; // expected-note {{declared here}} - (void) _anIvar; // expected-error {{instance variable '_anIvar' cannot be accessed because 'self' has been redeclared}} + C* self; + (void) _anIvar; } } - (void)doAThing { ^{ - id self; // expected-note {{declared here}} - (void)_anIvar; // expected-error {{instance variable '_anIvar' cannot be accessed because 'self' has been redeclared}} + id self; + (void)_anIvar; }(); } @end