Bug in wimp.h

Chris Rutter chris at willow.armlinux.org
Wed Aug 9 21:14:22 BST 2000


On Wed, 09 Aug 2000 08:42:35 Tony van der Hoff wrote:

> This does indeed look wrong. However, is it actually a problem? 

Well, potentially; take the example code:

    char nm[12]; 
    nm[0] = '*';
    nm[1] = '\0';
    wimp_load_template(...); /* Fetch the name of the next template */
    for (i = 1; i < 12; i++)
      /* ... do something with nm[i] ... */

The compiler's perfectly at liberty to feed you back nm[0] == '*' and
nm[1] == '\0' after that call, when clearly those memory locations will
have been updated.

Let's say we have a code fragment like this:

    sub     a3, sp, #48      ; (a3) = &nm[0]
    mov     v4, #'*'         ; nm[0] = '*'
    strb    v4, [a3, #0]
    mov     v4, #0           ; nm[1] = 0
    strb    v4, [a3, #1]
    [prepare arguments]
    bl      wimp_load_template
    [set up a loop where `i' is kept in v4]

On the first loop iteration, the compiler doesn't need to bother loading
the byte.

If that seems too contrived, here's another example:

    void foo (const int *a) { *((int *) a) = 4; }

    int a = 3;
    foo(&a);
    printf("%d", a);

printf() will surely yield "3", there, if its argument is declared const.

`const' is very dangerous, because it on a practical level, it's saying
that any values hanging around in registers of any kind are still valid
after a call -- i.e. no reload forced.

It's an extremely powerful declaration, because it can lead the compiler
to rearrange its whole function layout profoundly to leave values lying
around in uncorrupted registers to reduce memory transfer.

`const' is very very important: it should never be left out when it can
be put it, but more than that, it should never be put it when it's not
valid to do so.  Very very confusing and bad things can happen otherwise.

Having said all that, I can't persuade gcc 2.95/i386 or Norcroft C 5 to
actually `do the wrong thing'; mainly because they always seem to use
a1--a4 for the sorts of values which might get corrupted, and hence
always have to reload them after a function call /anyway/.  Either that
or I'm just preaching my misunderstanding of C, which is possible.

> In any case, I don't think it'll break any existing code if we were just
> to change it, so unless someone else can think of a problem, I'll
> schedule it for the next release.

No; you're allowed to cast in the `less lenient direction'.  Norcroft will
generate an error, though, if you implicitly cast the other way (whereas
all other C compilers don't care unless you ask them to).

c.





More information about the oslib-user mailing list