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
next prev parent 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).