On 04/25/2014 04:07 AM, Mike Stump wrote:
On Apr 24, 2014, at 4:09 PM, Dimitris Papavasiliou<dpapa...@gmail.com>  wrote:
On 04/24/2014 07:00 PM, Mike Stump wrote:
On Feb 6, 2014, at 1:25 AM, Dimitris Papavasiliou<dpapa...@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
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}
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 <dpapa...@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
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 <dpapa...@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 <dpapa...@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 <dpapa...@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 <dpapa...@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 <dpapa...@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 <dpapa...@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 <dpapa...@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 <dpapa...@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 <dpapa...@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 via email to