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

Reply via email to