public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Dimitris Papavasiliou <dpapavas@gmail.com>
To: Mike Stump <mikestump@comcast.net>
Cc: "gcc-patches@gcc.gnu.org Patches" <gcc-patches@gcc.gnu.org>
Subject: Re: [PATCH] Add a couple of dialect and warning options regarding Objective-C instance variable scope
Date: Fri, 25 Apr 2014 16:50:00 -0000	[thread overview]
Message-ID: <535A8EA8.5040706@gmail.com> (raw)
In-Reply-To: <757BB622-2CA8-4C9A-BCA9-AAD1FDF8F14F@comcast.net>

[-- Attachment #1: Type: text/plain, Size: 1888 bytes --]

On 04/25/2014 04:07 AM, Mike Stump wrote:
> On Apr 24, 2014, at 4:09 PM, Dimitris Papavasiliou<dpapavas@gmail.com>  wrote:
>> On 04/24/2014 07:00 PM, Mike Stump wrote:
>>> On Feb 6, 2014, at 1:25 AM, Dimitris Papavasiliou<dpapavas@gmail.com>  wrote:
>>>> This is a patch regarding a couple of Objective-C related dialect options and warning switches.
>>>
>>> Ok.
>>>
>>> Committed revision 209753.
>>>
>>> If you could, please add documentation and a test case.
>>
>> Thanks for taking the time to look at this, although to be honest I didn't expect a straight merge into the trunk.
>
> DonÂ’t submit changes you donÂ’t want!  :-)
>
>> I'll add documentation and test cases as soon as I figure out how.
>
> Just copy testsuite/objc.dg/private-2.m into shadow-1.m and then `fixÂ’ it to test what you want.  If you need one with and one without a flag, copy it twice and use something like:
>
> // { dg-options "-Wshadow" }
>
> on it.  Type make RUNTESTFLAGS=dg.exp=shadow-1.m check-objc to test it.
>
> For the doc, just find a simple option in the part of the manual you want to put it in, and copy it.  We document the non-default, (Wno-shadow-ivar for example) options.

I'm attaching three additional patches:

documentation.patch:  This adds documentation for the three additional 
switches plus a small change to reflect the fact that -Wshadow now 
controls instance variable shadowing as well.

tests.patch:  This adds 9 test cases that test both the intended 
behavior of the added switches as well as the default behavior in their 
absence.

enabledby_wshadow.patch:  This adds the proposed change to allow 
specifying -Wno-shadow to turn off -Wshadow-ivar as well plus one more 
test to make sure that it happens.

I've run make check-objc with all these changes and everything seems to 
be fine.  Let me know if you need anything else and thanks again for 
your time.

Dimitris

[-- Attachment #2: documentation.patch --]
[-- Type: text/x-patch, Size: 2872 bytes --]

Index: gcc/doc/invoke.texi
===================================================================
--- gcc/doc/invoke.texi	(revision 209787)
+++ gcc/doc/invoke.texi	(working copy)
@@ -216,6 +216,8 @@
 -fobjc-gc @gol
 -fobjc-nilcheck @gol
 -fobjc-std=objc1 @gol
+-fno-local-ivars @gol
+-fivar-visibility=@var{public|protected|private|package} @gol
 -freplace-objc-classes @gol
 -fzero-link @gol
 -gen-decls @gol
@@ -261,7 +263,7 @@
 -Wparentheses  -Wpedantic-ms-format -Wno-pedantic-ms-format @gol
 -Wpointer-arith  -Wno-pointer-to-int-cast @gol
 -Wredundant-decls  -Wno-return-local-addr @gol
--Wreturn-type  -Wsequence-point  -Wshadow @gol
+-Wreturn-type  -Wsequence-point  -Wshadow  -Wshadow-ivar @gol
 -Wsign-compare  -Wsign-conversion -Wfloat-conversion @gol
 -Wsizeof-pointer-memaccess @gol
 -Wstack-protector -Wstack-usage=@var{len} -Wstrict-aliasing @gol
@@ -2975,6 +2977,21 @@
 The GNU runtime currently always retains calls to @code{objc_get_class("@dots{}")}
 regardless of command-line options.
 
+@item -fno-local-ivars
+@opindex fno-local-ivars
+By default instance variables in Objective-C can be accessed as if
+they were local variables from within the methods of the class they're
+declared in.  This can lead to shadowing between instance variables
+and other variables declared either locally inside a class method or
+globally with the same name.  Specifying the @option{-fno-local-ivars}
+flag disables this behavior thus avoiding variable shadowing issues.
+
+@item -fivar-visibility=@var{public|protected|private|package}
+@opindex fivar-visibility
+Set the default instance variable visibility to the specified option
+so that instance variables declared outside the scope of any access
+modifier directives default to the specified visibility.
+
 @item -gen-decls
 @opindex gen-decls
 Dump interface declarations for all classes seen in the source file to a
@@ -4349,11 +4366,18 @@
 @item -Wshadow
 @opindex Wshadow
 @opindex Wno-shadow
-Warn whenever a local variable or type declaration shadows another variable,
-parameter, type, or class member (in C++), or whenever a built-in function
-is shadowed. Note that in C++, the compiler warns if a local variable
-shadows an explicit typedef, but not if it shadows a struct/class/enum.
+Warn whenever a local variable or type declaration shadows another
+variable, parameter, type, class member (in C++), or instance variable
+(in Objective-C) or whenever a built-in function is shadowed. Note
+that in C++, the compiler warns if a local variable shadows an
+explicit typedef, but not if it shadows a struct/class/enum.
 
+@item -Wshadow-ivar @r{(Objective-C only)}
+@opindex Wshadow-ivar
+@opindex Wno-shadow-ivar
+Warn whenever a local variable shadows an instance variable in an
+Objective-C method.
+
 @item -Wlarger-than=@var{len}
 @opindex Wlarger-than=@var{len}
 @opindex Wlarger-than-@var{len}

[-- Attachment #3: enabledby_wshadow.patch --]
[-- Type: text/x-patch, Size: 1417 bytes --]

Index: gcc/testsuite/objc.dg/shadow-2.m
===================================================================
--- gcc/testsuite/objc.dg/shadow-2.m	(revision 0)
+++ gcc/testsuite/objc.dg/shadow-2.m	(revision 0)
@@ -0,0 +1,33 @@
+/* Test disabling of warnings for shadowing instance variables.  */
+/* Author: Dimitris Papavasiliou <dpapavas@gmail.com>.  */
+/* { dg-do compile } */
+/* { dg-additional-options "-Wno-shadow" } */
+#include <objc/objc.h>
+
+@interface MyClass
+{
+@private
+  int private;
+
+@protected
+  int protected;
+
+@public
+  int public;
+}
+- (void) test;
+@end
+
+@implementation MyClass
+- (void) test
+{
+  int private = 12;
+  int protected = 12;
+  int public = 12;
+  int a;
+  
+  a = private;    /* { dg-warning "hides instance variable" "" { xfail *-*-* } } */
+  a = protected;  /* { dg-warning "hides instance variable" "" { xfail *-*-* } } */
+  a = public;     /* { dg-warning "hides instance variable" "" { xfail *-*-* } } */
+}
+@end
Index: gcc/c-family/c.opt
===================================================================
--- gcc/c-family/c.opt	(revision 209787)
+++ gcc/c-family/c.opt	(working copy)
@@ -685,7 +685,7 @@
 Warn if a selector has multiple methods
 
 Wshadow-ivar
-ObjC ObjC++ Var(warn_shadow_ivar) Init(1) Warning
+ObjC ObjC++ Var(warn_shadow_ivar) EnabledBy(Wshadow) Init(1) Warning
 Warn if a local declaration hides an instance variable
 
 Wsequence-point

[-- Attachment #4: tests.patch --]
[-- Type: text/x-patch, Size: 8817 bytes --]

Index: gcc/testsuite/objc.dg/shadow-1.m
===================================================================
--- gcc/testsuite/objc.dg/shadow-1.m	(revision 0)
+++ gcc/testsuite/objc.dg/shadow-1.m	(revision 0)
@@ -0,0 +1,33 @@
+/* Test disabling of warnings for shadowing instance variables.  */
+/* Author: Dimitris Papavasiliou <dpapavas@gmail.com>.  */
+/* { dg-do compile } */
+/* { dg-additional-options "-Wno-shadow-ivar" } */
+#include <objc/objc.h>
+
+@interface MyClass
+{
+@private
+  int private;
+
+@protected
+  int protected;
+
+@public
+  int public;
+}
+- (void) test;
+@end
+
+@implementation MyClass
+- (void) test
+{
+  int private = 12;
+  int protected = 12;
+  int public = 12;
+  int a;
+  
+  a = private;    /* { dg-warning "hides instance variable" "" { xfail *-*-* } } */
+  a = protected;  /* { dg-warning "hides instance variable" "" { xfail *-*-* } } */
+  a = public;     /* { dg-warning "hides instance variable" "" { xfail *-*-* } } */
+}
+@end
Index: gcc/testsuite/objc.dg/ivar-scope-1.m
===================================================================
--- gcc/testsuite/objc.dg/ivar-scope-1.m	(revision 0)
+++ gcc/testsuite/objc.dg/ivar-scope-1.m	(revision 0)
@@ -0,0 +1,21 @@
+/* Test instance variable scope.  */
+/* Author: Dimitris Papavasiliou <dpapavas@gmail.com>.  */
+/* { dg-do compile } */
+#include <objc/objc.h>
+
+@interface MyClass
+{
+  int someivar;
+}
+- (void) test;
+@end
+
+@implementation MyClass
+- (void) test
+{
+  int a;
+  
+  a = self->someivar;  /* Ok */
+  a = someivar;        /* { dg-error ".someivar. undeclared" "" { xfail *-*-* } } */
+}
+@end
Index: gcc/testsuite/objc.dg/ivar-scope-2.m
===================================================================
--- gcc/testsuite/objc.dg/ivar-scope-2.m	(revision 0)
+++ gcc/testsuite/objc.dg/ivar-scope-2.m	(revision 0)
@@ -0,0 +1,34 @@
+/* Test instance variable scope.  */
+/* Author: Dimitris Papavasiliou <dpapavas@gmail.com>.  */
+/* { dg-do compile } */
+/* { dg-additional-options "-fno-local-ivars" } */
+#include <objc/objc.h>
+
+@interface MyClass
+{
+  int someivar;
+}
+- (void) testscope;
+- (void) testshadowing;
+@end
+
+@implementation MyClass
+- (void) testscope
+{
+  int a;
+
+  a = self->someivar;  /* Ok */
+  a = someivar;        /* { dg-error ".someivar. undeclared" } */
+}
+
+- (void) testshadowing
+{
+  int someivar = 1;
+  int a;
+
+  /* Since instance variables don't have local scope no shadowing
+     should occur. */
+  
+  a = someivar;        /* { dg-warning "hides instance variable" "" { xfail *-*-* } } */
+}
+@end
Index: gcc/testsuite/objc.dg/ivar-scope-3.m
===================================================================
--- gcc/testsuite/objc.dg/ivar-scope-3.m	(revision 0)
+++ gcc/testsuite/objc.dg/ivar-scope-3.m	(revision 0)
@@ -0,0 +1,60 @@
+/* Test instance variable scope.  */
+/* Author: Dimitris Papavasiliou <dpapavas@gmail.com>.  */
+/* { dg-do run } */
+/* { dg-additional-options "-Wno-shadow-ivar" } */
+#include "../objc-obj-c++-shared/TestsuiteObject.m"
+#include <objc/objc.h>
+
+extern void abort(void);
+
+int someivar = 1;
+
+@interface MyClass: TestsuiteObject
+{
+  int someivar;
+}
+- (int) get;
+- (int) getHidden;
+@end
+
+@implementation MyClass
+- init
+{
+  someivar = 2;
+
+  return self;
+}
+
+- (int) get
+{
+  return someivar;
+}
+
+- (int) getHidden
+{
+  int someivar = 3;
+  
+  return someivar;
+}
+@end
+
+int main(void)
+{
+  MyClass *object;
+
+  object = [[MyClass alloc] init];
+
+  /* Check whether the instance variable hides the global variable. */
+  
+  if ([object get] != 2) {
+    abort();
+  }
+
+  /* Check whether the local variable hides the instance variable. */
+  
+  if ([object getHidden] != 3) {
+    abort();
+  }
+
+  return 0;
+}
Index: gcc/testsuite/objc.dg/ivar-scope-4.m
===================================================================
--- gcc/testsuite/objc.dg/ivar-scope-4.m	(revision 0)
+++ gcc/testsuite/objc.dg/ivar-scope-4.m	(revision 0)
@@ -0,0 +1,86 @@
+/* Test instance variable scope.  */
+/* Author: Dimitris Papavasiliou <dpapavas@gmail.com>.  */
+/* { dg-do run } */
+/* { dg-additional-options "-Wno-shadow-ivar -fno-local-ivars" } */
+#include "../objc-obj-c++-shared/runtime.h"
+#include <objc/objc.h>
+
+extern void abort(void);
+
+int someivar = 1;
+
+@interface MyClass
+{
+  Class isa;
+  int someivar;
+}
+
++ (id) new;
++ (id) alloc;
+- (id) init;
+- (int) getGlobal;
+- (int) getInstance;
+- (int) getHidden;
+@end
+
+@implementation MyClass
++ (id) new
+{
+  return [[self alloc] init];
+}
+
++ (id) alloc
+{
+  return class_createInstance (self, 0);
+}
+
+- (id) init
+{
+  self->someivar = 2;
+
+  return self;
+}
+
+- (int) getGlobal
+{
+  return someivar;
+}
+
+- (int) getInstance
+{
+  return self->someivar;
+}
+
+- (int) getHidden
+{
+  int someivar = 3;
+  
+  return someivar;
+}
+@end
+
+int main(void)
+{
+  id object;
+
+  object = [MyClass new];
+
+  /* Check for aliasing between instance variable and global
+     variable. */
+
+  if ([object getGlobal] != 1) {
+    abort();
+  }
+  
+  if ([object getInstance] != 2) {
+    abort();
+  }
+
+  /* Check wheter the local variable hides the instance variable. */
+  
+  if ([object getHidden] != 3) {
+    abort();
+  }
+
+  return 0;
+}
Index: gcc/testsuite/objc.dg/ivar-visibility-1.m
===================================================================
--- gcc/testsuite/objc.dg/ivar-visibility-1.m	(revision 0)
+++ gcc/testsuite/objc.dg/ivar-visibility-1.m	(revision 0)
@@ -0,0 +1,33 @@
+/* Test instance variable visibility.  */
+/* Author: Dimitris Papavasiliou <dpapavas@gmail.com>.  */
+/* { dg-do compile } */
+#include <objc/objc.h>
+
+@interface MySuperClass
+{
+    int someivar;
+}
+@end
+
+@implementation MySuperClass
+@end
+
+
+@interface MyClass : MySuperClass 
+@end
+
+@implementation MyClass
+@end
+
+@interface MyOtherClass
+- (void) test: (MyClass *) object;
+@end
+
+@implementation MyOtherClass
+- (void) test: (MyClass *) object
+{
+  int a;
+
+  a = object->someivar;   /* { dg-error "instance variable .someivar. is declared protected" } */
+}
+@end
Index: gcc/testsuite/objc.dg/ivar-visibility-2.m
===================================================================
--- gcc/testsuite/objc.dg/ivar-visibility-2.m	(revision 0)
+++ gcc/testsuite/objc.dg/ivar-visibility-2.m	(revision 0)
@@ -0,0 +1,34 @@
+/* Test instance variable visibility.  */
+/* Author: Dimitris Papavasiliou <dpapavas@gmail.com>.  */
+/* { dg-do compile } */
+/* { dg-additional-options "-fivar-visibility=protected" } */
+#include <objc/objc.h>
+
+@interface MySuperClass
+{
+    int someivar;
+}
+@end
+
+@implementation MySuperClass
+@end
+
+
+@interface MyClass : MySuperClass 
+@end
+
+@implementation MyClass
+@end
+
+@interface MyOtherClass
+- (void) test: (MyClass *) object;
+@end
+
+@implementation MyOtherClass
+- (void) test: (MyClass *) object
+{
+  int a;
+
+  a = object->someivar;   /* { dg-error "instance variable .someivar. is declared protected" } */
+}
+@end
Index: gcc/testsuite/objc.dg/ivar-visibility-3.m
===================================================================
--- gcc/testsuite/objc.dg/ivar-visibility-3.m	(revision 0)
+++ gcc/testsuite/objc.dg/ivar-visibility-3.m	(revision 0)
@@ -0,0 +1,34 @@
+/* Test instance variable visibility.  */
+/* Author: Dimitris Papavasiliou <dpapavas@gmail.com>.  */
+/* { dg-do compile } */
+/* { dg-additional-options "-fivar-visibility=private" } */
+#include <objc/objc.h>
+
+@interface MySuperClass
+{
+    int someivar;
+}
+@end
+
+@implementation MySuperClass
+@end
+
+
+@interface MyClass : MySuperClass 
+@end
+
+@implementation MyClass
+@end
+
+@interface MyOtherClass
+- (void) test: (MyClass *) object;
+@end
+
+@implementation MyOtherClass
+- (void) test: (MyClass *) object
+{
+  int a;
+
+  a = object->someivar;   /* { dg-error "instance variable .someivar. is declared private" } */
+}
+@end
Index: gcc/testsuite/objc.dg/ivar-visibility-4.m
===================================================================
--- gcc/testsuite/objc.dg/ivar-visibility-4.m	(revision 0)
+++ gcc/testsuite/objc.dg/ivar-visibility-4.m	(revision 0)
@@ -0,0 +1,34 @@
+/* Test instance variable visibility.  */
+/* Author: Dimitris Papavasiliou <dpapavas@gmail.com>.  */
+/* { dg-do compile } */
+/* { dg-additional-options "-fivar-visibility=public" } */
+#include <objc/objc.h>
+
+@interface MySuperClass
+{
+    int someivar;
+}
+@end
+
+@implementation MySuperClass
+@end
+
+
+@interface MyClass : MySuperClass 
+@end
+
+@implementation MyClass
+@end
+
+@interface MyOtherClass
+- (void) test: (MyClass *) object;
+@end
+
+@implementation MyOtherClass
+- (void) test: (MyClass *) object
+{
+  int a;
+
+  a = object->someivar;   /* { dg-error "instance variable .someivar. is declared (private|protected)" "" { xfail *-*-* } } */
+}
+@end

  reply	other threads:[~2014-04-25 16:31 UTC|newest]

Thread overview: 30+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-02-06  9:22 Dimitris Papavasiliou
2014-02-13 14:19 ` [PING][PATCH] " Dimitris Papavasiliou
2014-02-20 10:08   ` [PING^2][PATCH] " Dimitris Papavasiliou
2014-02-27  9:41     ` [PING^3][PATCH] " Dimitris Papavasiliou
2014-03-06 17:41       ` [PING^4][PATCH] " Dimitris Papavasiliou
2014-03-13  9:52         ` Dimitris Papavasiliou
2014-03-23  1:32           ` [PING^6][PATCH] " Dimitris Papavasiliou
2014-03-28 10:11             ` [PING^7][PATCH] " Dimitris Papavasiliou
2014-04-03 15:29               ` [PING^8][PATCH] " Dimitris Papavasiliou
2014-04-24 10:39                 ` Dimitris Papavasiliou
2014-04-24 20:29                   ` Jakub Jelinek
2014-04-25  0:17                     ` Dimitris Papavasiliou
2014-04-25  1:07                       ` Mike Stump
2014-04-25 11:40                         ` Dimitris Papavasiliou
2014-04-24 16:03 ` [PATCH] " Mike Stump
2014-04-24 23:16   ` Dimitris Papavasiliou
2014-04-25  3:20     ` Mike Stump
2014-04-25 16:50       ` Dimitris Papavasiliou [this message]
2014-04-25 16:53         ` Mike Stump
2014-04-28 10:37           ` Dimitris Papavasiliou
2014-05-05  7:31             ` Dimitris Papavasiliou
2014-05-12  7:49               ` Dimitris Papavasiliou
2014-05-12 16:25             ` Mike Stump
2014-05-12 18:57               ` Dimitris Papavasiliou
2014-05-12 19:14                 ` Mike Stump
2014-05-12 20:53             ` Mike Stump
2014-05-13 14:17               ` Dimitris Papavasiliou
  -- strict thread matches above, loose matches on Subject: below --
2013-06-09 21:44 Dimitris Papavasiliou
2013-06-24 12:09 ` Dimitris Papavasiliou
2013-07-02  8:05   ` Dimitris Papavasiliou

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=535A8EA8.5040706@gmail.com \
    --to=dpapavas@gmail.com \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=mikestump@comcast.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).