Bug 7993 - [3.4/4.0 regression] private variables cannot be shadowed in subclasses
Summary: [3.4/4.0 regression] private variables cannot be shadowed in subclasses
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: objc (show other bugs)
Version: 3.4.0
: P3 critical
Target Milestone: 3.4.1
Assignee: Zack Weinberg
URL:
Keywords: rejects-valid
Depends on:
Blocks:
 
Reported: 2002-09-20 17:56 UTC by lminder
Modified: 2005-02-09 02:18 UTC (History)
8 users (show)

See Also:
Host: i686-pc-linux-gnu
Target: *-*-* except *-*-darwin*
Build: i686-pc-linux-gnu
Known to work: 3.3
Known to fail: 3.4.0 4.0.0
Last reconfirmed: 2004-03-30 01:44:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description lminder 2002-09-20 17:56:01 UTC
If an instance variable is declared @private, the same variable name
can't be reused as name for local variables when implementing methods 
of subclasses.

This is wrong, because when writing subclasses you should not have to worry
about private implementation details of the superclass, such as names of
private variables. (I don't know, however, any official specification of
the Objective-C language, and therefore can't refer to any document
confirming my claim about the purpose of @private.)

The problem occurs in any of the gcc 3.x-versions I tested.

Release:
3.3 20020916 (experimental)

Environment:
System: Linux fanzthesecond 2.4.18 #33 Thu Jul 18 04:56:44 CEST 2002 i686 unknown
Architecture: i686

	
host: i686-pc-linux-gnu
build: i686-pc-linux-gnu
target: i686-pc-linux-gnu
configured with: ../gcc-20020916/configure --enable-languages=objc

How-To-Repeat:

The following code reproduces the problem:

@interface Base {
	@private
	int f;
}
@end

@interface Sub : Base {
}
-(float)squareOf:(float)f;
@end

@implementation Sub

-(float)squareOf:(float)g
{
	float f = g;
	return f*f;
}
@end

Compiling this I get the following error messages:

test1.m: In function `-[Sub squareOf:]':
test1.m:17: error: instance variable `f' is declared private
test1.m:17: warning: local declaration of `f' hides instance variable
test1.m:17: error: instance variable `f' is declared private
test1.m:17: warning: local declaration of `f' hides instance variable
Comment 1 Andrew Pinski 2003-05-25 22:14:43 UTC
confirmed error on mainline (20030525).
confirmed working on gcc version 2.95.3 20010125 (prerelease).
There fore this is regression from 2.95.3.
Comment 2 Andrew Pinski 2003-06-24 00:04:10 UTC
The error happens also happens in 3.0.4.
Comment 3 Andrew Pinski 2003-06-24 00:13:51 UTC
For some reason on powerpc-apple-darwin6.6 this testcase passes with the mainline (20030623) 
and 3.3.1 (20030616), yes this does not make sense (except that on darwin some things dealing 
with objective-c is different but it even passes with -fgnu-runtime). 
Comment 4 Andrew Pinski 2003-07-12 00:05:28 UTC
This happens every where except on *-*-darwin*.
Comment 5 Wolfgang Bangerth 2003-07-15 17:50:16 UTC
A patch for this has been submitted a long time ago here:
  http://gcc.gnu.org/ml/gcc-patches/2002-09/msg01497.html
Comment 6 Mark Mitchell 2003-07-20 01:12:06 UTC
Stan Shebs wrote this message:

  http://gcc.gnu.org/ml/gcc/2003-07/msg01168.html

Hopefully, his pondering will yield a decision soon. :-)

In the meantime, I'm postponing this PR until GCC 3.3.2.  If Stan makes a
decision soon we can still put this patch in GCC 3.3.1.
Comment 7 Stan Shebs 2003-09-09 21:12:07 UTC
Yes, this change should be made, and would be reasonable for 3.3.2. (It looks
like a side effect of a long-ago reorg by Zack.)
Comment 8 Steven Bosscher 2003-10-04 07:13:15 UTC
Stan,

This Bug 7993 is targeted for 3.3.2, and a patch has been pending for more than
a _year_ now!!! (http://gcc.gnu.org/ml/gcc-patches/2002-09/msg01497.html)

You said about the patch:
"Yes, this change should be made, and would be reasonable for 3.3.2. (It looks
like a side effect of a long-ago reorg by Zack.)"

So, why hasn't the patch been commited (or has it) and the bug been closed?
Comment 9 Mark Mitchell 2003-10-16 02:36:51 UTC
I have no idea why the patch hasn't been applied, but I'm not going to take
chances.  Postponed until GCC 3.3.3.

Stan, can you at least put this in on the mainline?
Comment 10 Andrew Pinski 2003-10-30 09:36:43 UTC
Zem could you look at this bug, there is a patch that Stan says is okay but he has not 
applied it yet, there is a whole history, it even been okayed for 3.3.3, could you apply it on 
the mainline and the 3.3 branch.
Thanks.
Comment 11 Zack Weinberg 2003-12-02 00:13:49 UTC
Brief experimentation on x86-linux indicates that mainline still has the issue
and that the patch doesn't fit on mainline anymore. I'd like to ask that this
_not_ be addressed on mainline just yet as I am about to undertake more work on
c-decl.c which may affect the patch.

I don't see any reason why this shouldn't be applied at once to the 3.3 branch.
Comment 12 Gabriel Dos Reis 2003-12-21 18:22:10 UTC
Zack, Stan and Zem --

Can anyone of you tell me if I should close this on 3.3.3 as
WONTFIX?  It looks to me that it is taking long to make decision
on this bug and related patch.  

-- Gaby
Comment 13 Zack Weinberg 2003-12-21 18:44:03 UTC
As I said in my earlier comment, I don't see any reason why the existing patch
should not be applied at once to the 3.3 branch.  The bug should then be retitled
a 3.4 regression and reassigned to me.

zw
Comment 14 Gabriel Dos Reis 2003-12-21 18:58:13 UTC
Subject: Re:  [3.3/3.4 regression] private variables cannot be shadowed in subclasses

"zack at gcc dot gnu dot org" <gcc-bugzilla@gcc.gnu.org> writes:

| As I said in my earlier comment, I don't see any reason why the
| existing patch should not be applied at once to the 3.3 branch.  The
| bug should then be retitled a 3.4 regression and reassigned to me.

Thanks for the prompt reply.

-- Gaby
Comment 15 CVS Commits 2004-01-14 07:52:43 UTC
Subject: Bug 7993

CVSROOT:	/cvs/gcc
Module name:	gcc
Branch: 	gcc-3_3-branch
Changes by:	gdr@gcc.gnu.org	2004-01-14 07:52:39

Modified files:
	gcc            : ChangeLog 
	gcc/objc       : objc-act.c 
Added files:
	gcc/testsuite/objc.dg: private-1.m private-2.m 

Log message:
	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.

Patches:
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/ChangeLog.diff?cvsroot=gcc&only_with_tag=gcc-3_3-branch&r1=1.16114.2.879&r2=1.16114.2.880
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/objc/objc-act.c.diff?cvsroot=gcc&only_with_tag=gcc-3_3-branch&r1=1.160&r2=1.160.4.1
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/objc.dg/private-1.m.diff?cvsroot=gcc&only_with_tag=gcc-3_3-branch&r1=NONE&r2=1.1.2.1
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/objc.dg/private-2.m.diff?cvsroot=gcc&only_with_tag=gcc-3_3-branch&r1=NONE&r2=1.1.2.1

Comment 16 Gabriel Dos Reis 2004-01-14 07:54:37 UTC
Fixed for 3.3.3 (applied patch referenced in audit trail).

Reassigned to ZAck -- per his request
Comment 17 Gabriel Dos Reis 2004-01-14 07:58:57 UTC
Gloops. This is not fixed in 3.4.0 
Looks like one can't set things straight with bugzilla and one
has to click,reload, click, ... for every single of informatiion.
Comment 18 Gabriel Dos Reis 2004-01-14 08:00:41 UTC
balh.

bugzilla seems to require noise traffic for every single piece of information.
Comment 19 Mark Mitchell 2004-03-16 22:35:58 UTC
As sad as it is that this bug has not yet been fixed, it is still not a
showstopper.  So, I've postponed it until 3.4.1.
Comment 20 Mark Mitchell 2004-05-31 22:26:50 UTC
Zack --

Is it practical to fix this in 3.4.1?  Or, is that going to require a bunch of
your c-decl.c patches?  In fact, in general, would you please go through the
3.4.1 regressions and indicate which you think are impractical to fix without
the c-decl.c surgery?

Thanks,

-- Mark
Comment 21 Zack Weinberg 2004-06-01 04:19:20 UTC
This patch can be fixed in 3.4 without the c-decl.c rewrite.  The existing patch
will work with only minor tweaks.  I am testing 3.4 and mainline patches for
this bug right now.
Comment 22 Zack Weinberg 2004-06-01 07:28:41 UTC
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  <nicola@brainstorm.co.uk>

 	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 <nicola@brainstorm.co.uk>.  */
+/* { dg-do compile } */
+#include <objc/objc.h>
+
+@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 <nicola@brainstorm.co.uk>.  */
+/* { dg-do compile } */
+#include <objc/objc.h>
+
+@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
Comment 23 CVS Commits 2004-06-01 07:34:46 UTC
Subject: Bug 7993

CVSROOT:	/cvs/gcc
Module name:	gcc
Branch: 	gcc-3_4-branch
Changes by:	zack@gcc.gnu.org	2004-06-01 07:34:40

Modified files:
	gcc            : ChangeLog 
	gcc/objc       : objc-act.c 
	gcc/testsuite  : ChangeLog 
Added files:
	gcc/testsuite/objc.dg: private-1.m private-2.m 

Log message:
	2004-06-01  Nicola Pero  <nicola@brainstorm.co.uk>
	
	Fix 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.

Patches:
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/ChangeLog.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=2.2326.2.463&r2=2.2326.2.464
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/objc/objc-act.c.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=1.202.4.1&r2=1.202.4.2
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/ChangeLog.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=1.3389.2.193&r2=1.3389.2.194
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/objc.dg/private-1.m.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=NONE&r2=1.1.8.1
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/objc.dg/private-2.m.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=NONE&r2=1.1.8.1

Comment 24 CVS Commits 2004-06-01 07:40:10 UTC
Subject: Bug 7993

CVSROOT:	/cvs/gcc
Module name:	gcc
Changes by:	zack@gcc.gnu.org	2004-06-01 07:40:03

Modified files:
	gcc            : ChangeLog 
	gcc/objc       : objc-act.c 
	gcc/testsuite  : ChangeLog 
Added files:
	gcc/testsuite/objc.dg: private-1.m private-2.m 

Log message:
	2004-06-01  Nicola Pero  <nicola@brainstorm.co.uk>
	
	Fix 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.

Patches:
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/ChangeLog.diff?cvsroot=gcc&r1=2.3811&r2=2.3812
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/objc/objc-act.c.diff?cvsroot=gcc&r1=1.214&r2=1.215
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/ChangeLog.diff?cvsroot=gcc&r1=1.3800&r2=1.3801
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/objc.dg/private-1.m.diff?cvsroot=gcc&r1=1.1&r2=1.2
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/objc.dg/private-2.m.diff?cvsroot=gcc&r1=1.1&r2=1.2

Comment 25 Zack Weinberg 2004-06-01 07:41:33 UTC
fixed.