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.
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:
I get this with small and medium:
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.
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
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
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.