On Wed, Dec 21, 2016 at 12:33 PM, Andre Vehreschild <ve...@gmx.de> wrote: > Hi Janne, > >> But yes, I'm still seeing the warning messages with -O1 for >> allocate_deferred_char_scalar_1.f03. AFAICT it's a bogus warning, but >> I don't know how to get rid of it.. > > No, that warning isn't at all bogus. The warning in fact is astonishingly > precise. When I remember correctly, then the warning complains about trying to > put a string of length 8 into memory of length 5. There is never a memory > access error at runtime, because the code generated ensures that only 5 chars > are copied, but I am impressed by the analysis done by some intermediate step > of gcc. It figures, that memory is available for 5 characters only derefing a > "static/constant" pointer and then learning that initially 8 chars are to be > copied. I already tried to fix this by only generating code to copy the 5 > characters and make this knowledge available to the gimplifier, but I failed > to > deref the pointer and get the information statically. So IMHO the warning is > not bogus. It is absolutely correct and it is quite sophisticated to learn all > the necessary facts, but I didn't find a way to get this done in the > front-end. > We might be able to prevent the warning when there is a chance to add some > hook > into the middle stages of the compiler, telling it, that everything is fine. > But I have no idea what is possible and available there.
I suspect it's complaining about (from the -fdump-tree-original): { integer(kind=8) D.3598; unsigned long D.3599; D.3598 = *_p; D.3599 = (unsigned long) D.3598 + 18446744073709551608; if (D.3598 != 0) { if ((unsigned long) D.3598 <= 8) { __builtin_memmove ((void *) *p, (void *) &"12345679"[1]{lb: 1 sz: 1}, (unsigned long) D.3598); } else { __builtin_memmove ((void *) *p, (void *) &"12345679"[1]{lb: 1 sz: 1}, 8); __builtin_memset ((void *) *p + 8, 32, D.3599); } } } 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); } ? -- Janne Blomqvist