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.)

Reply via email to