http://gcc.gnu.org/bugzilla/show_bug.cgi?id=39753
--- Comment #13 from John Engelhart <john.engelhart at gmail dot com> 2011-03-19 04:06:28 UTC --- I'm the original reporter. At this point, I no longer have any specific examples that demonstrate this problem (this was filed quite some time ago). m...@gcc.gnu.org: > So, I'm sort of skeptical of this problem. Please engineer a test case that > shows bad code. Are the fundamental principles and reasoning for why this could be a problem sound? Specifically: Can pointers to Objective-C objects break C99's strict aliasing rules? // objc method rewritten as a C function, for those not familiar with ObjC void objc_method( MYSuperMutableArray self, // subclass of NSMutableArray SEL _cmd, NSMutableArray *mutableArray, NSArray *array) { int myCount = count; // compiler rewrites as self->count int arrayCount = array->count; int mutableArrayCount = mutableArray->count; int totalCount = mutableArray->count++; totalCount += array->count; totalCount += count; } Does this break C99 strict aliasing rules? What if self, array, and mutableArray all point to the same thing (i.e., self = array = mutableArray)? The fact is that Objective-C uses pointers to objects in a way that violates C99 strict aliasing rules. I don't think anyone has disputed this point. If this is indeed the case, then there exists the possibility of generating bad optimized code when you apply C99's strict type based aliasing rules to pointers to Objective-C objects. > I think you'll find it is a rather bit harder than you expect. How difficult it is, or how unlikely it might be in practice, does not change the fact that C99's strict aliasing rules are not compatible with Objective-C's use of pointers to objects. As someone suggested, the easiest solution is to simply automatically tag them with "may alias" and be done with it. This turns it from a "maybe / hypothetically / phase of the moon" in to "can not possibly be a problem / correct by design." > I think most dynamic things happen at the end of a function call, that you > can't see into (the Object-C run-time), and those things that happen before > that point, must happen before that point, and those things that happen after > that point, can't come before it. Objective-C adds a ton of these type of > calls all over the place, which controls just how far the optimizer can move > anything. Escape analysis should quickly realize that it doesn't own much of > anything, which further prevents almost anything from happening. This is true of any violation of C99's strict aliasing rules- certain bits of codes, or usage styles, can make a huge difference as to whether or not a strict aliasing violation ends up manifesting itself as a genuine problem. With pure C99 code, the programmer has basically two options: Don't do something that the C99 spec says is undefined behavior, or result to compiler hacks, like adding __attribute__((may_alias)) or -fno-strict-aliasing. You might not agree with the C99 spec, but the spec is Correct(tm), even the parts that are wrong. Objective-C has no formal spec. This is a bit of a problem, for a lot of reasons. However, it is often defined as a "strict super-set of C". If you use -std=(gnu|c)99, I interpret this to mean "a strict super-set of C99". I won't get in to definitions, but both super-set, and the qualifier "strict" have very specific meanings. The short version is that it doesn't really leave you a whole lot of wiggle room to pick and choose which parts of the C99 spec you want to include in your interpretation of Objective-C- you're basically stuck importing the C99 spec wholesale. This particular bug is due to the fact that C99 is not Objective-C. C99 was not written (to my knowledge) in a way that took the needs of Objective-C in to account. For better or for worse, C99's strict aliasing and Objective-C (as it is used today) just do not get along. It's unreasonable to expect the vast body of Objective-C code to change to a C99 sanctioned way of accomplishing object oriented inheritance (don't, or use "unions"!), so we're sort of stuck with grand-fathering in Objective-C's wild C99 strict-aliasing violating ways. > As for an > individual pointer, statically, the type should always be reasonable, though, > we do expect to up-cast and downcast pointers. In Objective-C? Sure. But this (usually) violates C99's strict aliasing rules. This is why this bug exists- Objective-C needs to be able to do this, but it also needs to let the C99 part of the compiler know that the usual type base strict-aliasing rules don't apply to a pointer to an Objective-C object (i.e., treat it as void * or char *, aliases anything). http://mail-index.netbsd.org/tech-kern/2003/08/11/0001.html http://mail.python.org/pipermail/python-dev/2003-July/036898.html http://lkml.org/lkml/2003/2/26/158 http://cellperformance.beyond3d.com/articles/2006/06/understanding-strict-aliasing.html >From Apples gcc-5664/gcc/config/i386.c: void optimization_options (int level, int size ATTRIBUTE_UNUSED) { /* APPLE LOCAL begin disable strict aliasing; breaks too much existing code. */ #if TARGET_MACHO flag_strict_aliasing = 0; #endif /* APPLE LOCAL end disable strict aliasing; breaks too much existing code. */ You should take particular note of this last little bit- you can't even enable -fstrict-aliasing on Apples compilers, which is arguably the compiler used by the majority of Objective-C developers. I'd argue that this little detail is masking how big this problem is in practice (i.e., the fact that no one is reporting it is can't be used as an indicator of how wide spread the problem is in real world code). > Some on the C side of things > might disagree, but, once the C people realize that up-casting and > down-casting > are both valid, then even this is fine. Errgh, sorry, but if by "C side of things" you mean C99 as it is defined in WG14/N1256 ISO/IEC 9899:TC3 (aka, the C99 spec), then I'm afraid you're wrong. > Once you combine all these factors, > there is no wiggle room left for the optimizer to do anything. ... and? This is like saying "Most of the time the C99 strict aliasing rules won't bite you in the ass. And most of the time is similar to almost never. And almost never has the word never in it, so it's obviously never a problem." > If you can find > any, test case please. We can then address the specific concern. > > Until then, we'll wait for a testcase. What? Sorry, but it seems to me like you acknowledge that C99's strict aliasing rules could potentially / theoretically cause a problem, then you did a lot of hand waving in which you rationalized that because the specific hand waving scenario you came up with probably doesn't suffer the problem, the problem must not exist. > As far as missing language definition bits, please describe a missing bit, be > specific. I can't think of any off the top of my head. Sorry, I'm not sure what you mean by "language definition bits". Do you mean an Objective-C language definition? There literally is none, unfortunately (as an aside, when this has been brought to Apples attention, the official response was "You should file a documentation bug." Seriously.)