https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108889

Paul Thomas <pault at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |pault at gcc dot gnu.org

--- Comment #5 from Paul Thomas <pault at gcc dot gnu.org> ---
(In reply to Tobias Burnus from comment #0)
> The following testcase shows the following -Wall warnings:
> 
> Warning: ‘reference.offset’ is used uninitialized [-Wuninitialized]
> Warning: ‘reference.dim[0].lbound’ is used uninitialized [-Wuninitialized]
> Warning: ‘reference.dim[0].ubound’ may be used uninitialized
> [-Wmaybe-uninitialized]
> 
> The warning (but not the issue) is new since GCC 12. The dump shows:
> 
>     D.4310 = reference.offset;
>     D.4311 = reference.dim[0].lbound;
>     D.4312 = reference.dim[0].ubound;
> 
>     D.4313 = D.4311 - D.4307;  // D.4307 = single.var.dim[0].lbound
> 
> But all expressions are actually re-evaluated later:
>         D.4317 = (real(kind=4)[0:] * restrict) reference.data == 0B;
>         if (D.4317) goto L.4;
> ...
>         L.4:;
> ...
>         reference.dim[0].lbound = single.var.dim...
>         reference.offset = -NON_LVALUE_EXPR <reference.dim[0].lbound>;
>         D.4310 = reference.offset;
>         D.4313 = reference.dim[0].lbound - D.4307;
> ...
>         L.5:;  /// If the shape was correct, there is a jump to here / L.5
>       while (1)
>         {
>           if (S.2 > D.4308) goto L.6;
>           (*D.4309)[(S.2 + D.4313) + D.4310] = (*D.4305)[S.2 + D.4306];
> 
> Thus, D.4313 + D.4310 needs to be evaluated in the no-(re)alloc case and in
> the needs-to-be allocated case.
> 
> 
> Thus, the produced code is fine at the end – even though there was
> uninitialized memory in between. — But this should be fixed, also to silence
> the warning.
> 
> * * * 
> 
> ! Testcase: Compile with -Wall
> 
> program main
>   implicit none
>  
>   type :: struct
>     real, allocatable :: var(:)
>   end type struct
>  
>   type(struct) :: single
>   real, allocatable :: reference(:)
>  
>   single%var = [1,2,3,4,5]
>   reference = single%var
> 
>   if (size(reference) /= size(single%var)) stop 1
>   if (lbound(reference, 1) /= 1) stop 3
>   if (any (reference /= single%var)) stop 3
> end

The offending temporaries are emerging out of the scalarizer, rather than
gfc_alloc_allocatable_for_assignment, and are used for the saved_offset and
deltas. These are set in gfc_alloc_allocatable_for_assignment  at lines
11378-11392, which is why the temporaries pop up again.

I'm thinking about it :-)

Cheers

Paul

Reply via email to