From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 18280 invoked by alias); 1 Jun 2004 07:29:01 -0000 Mailing-List: contact gcc-bugs-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Archive: List-Post: List-Help: Sender: gcc-bugs-owner@gcc.gnu.org Received: (qmail 18239 invoked by alias); 1 Jun 2004 07:28:58 -0000 Date: Tue, 01 Jun 2004 07:29:00 -0000 Message-ID: <20040601072858.18238.qmail@sourceware.org> From: "zack at codesourcery dot com" To: gcc-bugs@gcc.gnu.org In-Reply-To: <20020920175601.7993.lminder@gmx.net> References: <20020920175601.7993.lminder@gmx.net> Reply-To: gcc-bugzilla@gcc.gnu.org Subject: [Bug objc/7993] [3.4/3.5 regression] private variables cannot be shadowed in subclasses X-Bugzilla-Reason: CC X-SW-Source: 2004-06/txt/msg00043.txt.bz2 List-Id: ------- Additional Comments From zack at codesourcery dot com 2004-06-01 07:28 ------- Subject: 3.4/HEAD patches for PR 7993 PR 7993 (objc should allow shadowing private instance variables in subclasses) has been hanging around for a long time now, mainly because I thought the fix would be more work than "grab the patch out of the PR and tweak it a little to fit on mainline." I was wrong. Appended is the patch - basically the same as the one Nicola Pero wrote back in 2002 - I'm checking onto mainline and 3.4 branch. Tested on i686-linux. zw 2004-06-01 Nicola Pero PR objc/7993 * objc-act.c (is_private): Do not emit the 'instance variable %s is declared private' error. (is_public): Emit the error after calling is_private. (lookup_objc_ivar): If the instance variable is private, return 0 - the instance variable is invisible here. testsuite: * objc.dg/private-1.m, objc-dg/private-2.m: New testcases. =================================================================== Index: objc/objc-act.c --- objc/objc-act.c 15 May 2004 23:07:53 -0000 1.214 +++ objc/objc-act.c 1 Jun 2004 05:28:46 -0000 @@ -6467,15 +6467,9 @@ is_ivar (tree decl_chain, tree ident) int is_private (tree decl) { - if (TREE_PRIVATE (decl) - && ! is_ivar (CLASS_IVARS (implementation_template), DECL_NAME (decl))) - { - error ("instance variable `%s' is declared private", - IDENTIFIER_POINTER (DECL_NAME (decl))); - return 1; - } - else - return 0; + return (TREE_PRIVATE (decl) + && ! is_ivar (CLASS_IVARS (implementation_template), + DECL_NAME (decl))); } /* We have an instance variable reference;, check to see if it is public. */ @@ -6513,7 +6507,14 @@ is_public (tree expr, tree identifier) == CATEGORY_IMPLEMENTATION_TYPE)) && (CLASS_NAME (objc_implementation_context) == OBJC_TYPE_NAME (basetype)))) - return ! is_private (decl); + { + int private = is_private (decl); + + if (private) + error ("instance variable `%s' is declared private", + IDENTIFIER_POINTER (DECL_NAME (decl))); + return !private; + } /* The 2.95.2 compiler sometimes allowed C functions to access non-@public ivars. We will let this slide for now... */ @@ -9066,7 +9067,7 @@ lookup_objc_ivar (tree id) else if (objc_method_context && (decl = is_ivar (objc_ivar_chain, id))) { if (is_private (decl)) - return error_mark_node; + return 0; else return build_ivar_reference (id); } =================================================================== Index: testsuite/objc.dg/private-1.m --- testsuite/objc.dg/private-1.m 1 Jan 1970 00:00:00 -0000 +++ testsuite/objc.dg/private-1.m 1 Jun 2004 05:28:47 -0000 @@ -0,0 +1,59 @@ +/* Test errors for accessing @private and @protected variables. */ +/* Author: Nicola Pero . */ +/* { dg-do compile } */ +#include + +@interface MySuperClass +{ +@private + int private; + +@protected + int protected; + +@public + int public; +} +- (void) test; +@end + +@implementation MySuperClass +- (void) test +{ + private = 12; /* Ok */ + protected = 12; /* Ok */ + public = 12; /* Ok */ +} +@end + + +@interface MyClass : MySuperClass +@end + +@implementation MyClass +- (void) test +{ + /* Private variables simply don't exist in the subclass. */ + private = 12;/* { dg-error "undeclared" } */ + /* { dg-error "function it appears in" "" { target *-*-* } { 37 } } */ + + protected = 12; /* Ok */ + public = 12; /* Ok */ +} +@end + +int main (void) +{ + MyClass *m = nil; + + if (m != nil) + { + int access; + + access = m->private; /* { dg-error "is @private" } */ + access = m->protected; /* { dg-error "is @protected" } */ + access = m->public; /* Ok */ + } + + return 0; +} =================================================================== Index: testsuite/objc.dg/private-2.m --- testsuite/objc.dg/private-2.m 1 Jan 1970 00:00:00 -0000 +++ testsuite/objc.dg/private-2.m 1 Jun 2004 05:28:47 -0000 @@ -0,0 +1,54 @@ +/* Test warnings for shadowing instance variables. */ +/* Author: Nicola Pero . */ +/* { dg-do compile } */ +#include + +@interface MySuperClass +{ +@private + int private; + +@protected + int protected; + +@public + int public; +} +- (void) test; +@end + +@implementation MySuperClass +- (void) test +{ + /* FIXME: I wonder if the warnings shouldn't be better generated + when the variable is declared, rather than used! */ + int private = 12; + int protected = 12; + int public = 12; + int a; + + a = private; /* { dg-warning "hides instance variable" } */ + a = protected; /* { dg-warning "hides instance variable" } */ + a = public; /* { dg-warning "hides instance variable" } */ +} +@end + + +@interface MyClass : MySuperClass +@end + +@implementation MyClass +- (void) test +{ + int private = 12; + int protected = 12; + int public = 12; + int a; + + /* The private variable can be shadowed without warnings, because + * it's invisible, and not accessible, to the subclass! */ + a = private; /* Ok */ + a = protected; /* { dg-warning "hides instance variable" } */ + a = public; /* { dg-warning "hides instance variable" } */ +} +@end -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=7993