On Wed, Dec 21, 2016 at 1:50 PM, Andre Vehreschild <ve...@gmx.de> wrote: >> Here p is the character variable, and _p is the charlen. My guess is >> that the problem is that with -O1 it sees that the second memmove >> would overflow p, but it doesn't realize that branch is never taken. >> Cranking up the optimization level to -O2 and beyond makes it realize >> it, and thus the warning disappears. >> >> Perhaps one could rewrite that to something like >> >> __builtin_memmove ((void *) *p, (void *) &"12345679"[1]{lb: 1 sz: 1}, >> MIN_EXPR<(unsigned long) D.3598,8>); >> if ((unsigned long) D.3598 > 8) >> { >> __builtin_memset ((void*) *p + 8, 32, D.3599); >> } > > That looks interesting. It assumes though, that D.3598 will *never* be > negative. Because when it is negative 8 characters (cast to unsigned makes the > negative number huge) will be copied, while in the former code memmove will > reject the coping of a negative number of bytes. Therefore I propose to omit > the cast in the MIN_EXPR and make the constant 8 signed, too. That should > comply and mimick the former behavior more closely. What do you think? Who's > going to try?
Now when I think about this some more, I have a vague recollection that a long time ago it used to be something like that. The problem is that MIN_EXPR<CONSTANT, NON-CONSTANT> will of course be NON-CONSTANT, so the memcpy call can't be inlined. Hence it was changed to two separate __builtin_memmove() calls to have better opportunity to inline. So probably a no-go to change it back. :( -- Janne Blomqvist