[PATCH] C undefined behavior fix
Richard Henderson
rth@redhat.com
Fri Jan 4 18:05:00 GMT 2002
On Fri, Jan 04, 2002 at 04:12:41PM -0800, Linus Torvalds wrote:
> Which should be easy enough. I don't think anybody has even shown a
> real-life case where
>
> strcpy(p, "constant string" + constant)
>
> is actually used, much less a single case where it would make sense to
> "optimize" this when the constant is larger than the length of the string.
No. You miss the point.
Yes, it is very easy to adjust the code around the strcpy
optimization to prevent this particular case from happening.
I may do just that, but that doesn't solve the underlying
dispute.
What I am saying is, that if you write
static int a[4] __attribute__((section("one")));
static int b[4] __attribute__((section("two")));
and know that B directly follows A (because you put them there),
and try to use that knowledge in some way, you will lose.
Unless something has broken recently, the following should
succeed the link:
a[5] = 0;
b[0] = 1;
if (a[5])
link_error ();
What I don't seem to be expressing well (since you irrelevantly
brought up strcpy again), is that the accessing of a[5] is
exactly the same bug as the strcpy thing. In both cases you
are doing pointer arithmetic -- and accessing data -- beyond
the bounds of the known object.
If you would like gcc to be able to infer from
for (i = 0; i < n; ++i)
a[i] = b[0];
that B[0] is loop invariant and may be hoisted above the loop,
then GCC must be able to look past a PLUS with a complex
offset to see the SYMBOL_REF for A. And if we can do that,
then because of the way that GCC works, we will also look
past what ever integer arithmetic you did between casting
a pointer to an integer and back.
At which point we have to make a decision: Is it a reasonable
thing to allow a user to go between objects by virtue of
the 6.3.2.3 escape hatch, or do we can this optimization
until such time as we can distinguish a pointer-plus from
an integer-plus?
I could think of no situation -- in kernel, ld.so, or any other
traditionally nasty place -- that would require, or could even
make use of, allowing the movement between objects via integer
arithmetic. So I decided to disallow it.
Give me a counter-example that would be useful and MAYBE I'll
reconsider. I'll not change my mind just because you think
that you ought to be able to string together two implementation
defined casts to achieve ... what exactly?
r~
More information about the Gcc
mailing list