#354 Local 20bit data pointer corrupted by optimizer

4.7.x_development
open
nobody
None
7
2014-07-30
2013-07-01
Oliver
No

I think I found a pretty serious, well-hidden bug in 4.7.0-20120911 and/or its optimizer.

To reproduce try:
a main() with a (20-bit) data pointer as local variable *bufPtr. Then call a function g(&bufPtr) and pass a pointer to this variable. This function itself calls another function f() by its function-pointer fPtr (= &f).

The effect:
After the calls to g() and f() an sprintf() is not able to interpret %d anymore and does just nothing. This occurs only with memory-model "large" or "huge" and only if an optimizer -O, -O2 or -Os is used. As workaround we try to use memory-model "medium" (= 16bit-pointers to data only).

See attachment for the whole example code!

Realistic usecase: in our application g() is called allocateBuffer(&bufPtr) and fPtr is a callback which is assigned to a function of a module (= .h/.c) in an upper layer.

I don't think this bug is a duplicate of bug [#350]. I implemented a my_sprintf() and a my_printf() that do call va_start() and va_end() in the same function, but this bug still occurs.
It is not like bug [#345], because I do not see any compiler errors or warnings.
It may be related to bug [#352], but then I clearly propose to set the priority of both bugs to at least 7! This bug is quite hard to find, to understand and to work-around.

1 Attachments

Related

Bugs: #345
Bugs: #350
Bugs: #352

Discussion

  • Peter A. Bigot
    Peter A. Bigot
    2013-07-01

    Interestingly with memory model huge and -Os -O2 it appears to work. Can you duplicate that?

    With just -Os I get this on both huge and large:

    buffer  @ 0x01c62
    Hello  @ 0x01c62
    Hello  @ 0x01c62
    

    I get this with small and medium:

    buffer  @ 0x01c64
    Hello  @ 0x01c64
    42  @ 0x01c64
    

    Calling that the "correct" answer, and assuming my quick investigation was accurate, the bug is fixed in my development installation so it is probably #352.

    At this time I don't know when a new release that fixes this will be available.

     
  • Peter A. Bigot
    Peter A. Bigot
    2013-07-01

    I appreciate your efforts to create a reproducible test case. My time in support is limited since there is no funding, however I've attached a patch to [#352] that may solve your problem. Please try it and reply back here.

     

    Related

    Bugs: #352


    Last edit: Peter A. Bigot 2013-07-01
  • Oliver
    Oliver
    2013-07-02

    Thank you very much for publishing your patch to fix [#352]. I hope we have time soon to apply it, rebuild and test mspgcc with it. For the moment we continue with memory-model=medium.

    I can confirm your observations above. About your suggestion "-Os -O2": I guess only the last optimizer option counts, so "-Os -O2" is equal to "-O2" only. But I made a mistake. This error is only triggered by using memory-model=large or =huge together with -O or -Os. Meanwhile I saw that with -O2 or -O3 it always works as expected! But currently we think we see other problems when using -O2, therefore this is not a workaround for us at the moment.

     

    Related

    Bugs: #352

  • Peter A. Bigot
    Peter A. Bigot
    2013-07-02

    No; -Os and -O2 are cumulative, both turning on subsets of the available options (-Os the optimizations that are known to reduce size, -O2 the optimizations for speed at level 2). Since -O2 alone makes it work for you there's something it adds that eliminates the problem (probably optimizing away the call because everything in that example is in the same translation unit).

    There are known issues with large memory model that will not be worked around in mspgcc because gcc cannot cope with systems where sizeof(void*)!= sizeof(ptrdiff_t). -O2 is likely to increase the visibility of those problems.