https://gcc.gnu.org/g:aed4a2689dbc8ea7e60c1fab9e7f455d99e632b7

commit r15-6395-gaed4a2689dbc8ea7e60c1fab9e7f455d99e632b7
Author: Harald Anlauf <anl...@gmx.de>
Date:   Thu Dec 19 22:22:52 2024 +0100

    Fortran: potential aliasing of complex pointer inquiry references [PR118120]
    
            PR fortran/118120
            PR fortran/113928
    
    gcc/fortran/ChangeLog:
    
            * trans-array.cc (symbols_could_alias): If one symbol refers to a
            complex type and the other to a real type of the same kind, do not
            a priori exclude the possibility of aliasing.
    
    gcc/testsuite/ChangeLog:
    
            * gfortran.dg/aliasing_complex_pointer.f90: New test.

Diff:
---
 gcc/fortran/trans-array.cc                         | 17 +++++---
 .../gfortran.dg/aliasing_complex_pointer.f90       | 46 ++++++++++++++++++++++
 2 files changed, 57 insertions(+), 6 deletions(-)

diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index 82a2ae1f7479..52813857353f 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -5344,15 +5344,20 @@ static bool
 symbols_could_alias (gfc_symbol *lsym, gfc_symbol *rsym, bool lsym_pointer,
                     bool lsym_target, bool rsym_pointer, bool rsym_target)
 {
-  /* Aliasing isn't possible if the symbols have different base types.  */
-  if (gfc_compare_types (&lsym->ts, &rsym->ts) == 0)
-    return 0;
+  /* Aliasing isn't possible if the symbols have different base types,
+     except for complex types where an inquiry reference (%RE, %IM) could
+     alias with a real type with the same kind parameter.  */
+  if (!gfc_compare_types (&lsym->ts, &rsym->ts)
+      && !(((lsym->ts.type == BT_COMPLEX && rsym->ts.type == BT_REAL)
+           || (lsym->ts.type == BT_REAL && rsym->ts.type == BT_COMPLEX))
+          && lsym->ts.kind == rsym->ts.kind))
+    return false;
 
   /* Pointers can point to other pointers and target objects.  */
 
   if ((lsym_pointer && (rsym_pointer || rsym_target))
       || (rsym_pointer && (lsym_pointer || lsym_target)))
-    return 1;
+    return true;
 
   /* Special case: Argument association, cf. F90 12.4.1.6, F2003 12.4.1.7
      and F2008 12.5.2.13 items 3b and 4b. The pointer case (a) is already
@@ -5363,9 +5368,9 @@ symbols_could_alias (gfc_symbol *lsym, gfc_symbol *rsym, 
bool lsym_pointer,
          || (rsym->attr.dummy && !rsym->attr.contiguous
              && (!rsym->attr.dimension
                  || rsym->as->type == AS_ASSUMED_SHAPE))))
-    return 1;
+    return true;
 
-  return 0;
+  return false;
 }
 
 
diff --git a/gcc/testsuite/gfortran.dg/aliasing_complex_pointer.f90 
b/gcc/testsuite/gfortran.dg/aliasing_complex_pointer.f90
new file mode 100644
index 000000000000..7fc4a209b34b
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/aliasing_complex_pointer.f90
@@ -0,0 +1,46 @@
+! { dg-do run }
+! PR fortran/118120 - potential aliasing of complex pointer inquiry references
+!
+! Contributed by Slava Zakharin < szakharin at nvidia dot com >
+
+program main
+  implicit none
+  integer :: k
+  complex, target :: data(21)
+  do k=1,21
+     data(k) = cmplx(-k,0.0)
+  end do
+  call test(1, 1, data)
+! print *, data
+  if (     data(1)      /= -1.)           stop 1
+  if (any (data(2:)% re /= [(k,k=1,20)])) stop 2
+  call pr113928 ()
+contains
+  subroutine test(i, j, data)
+    integer :: i, j
+    complex, target  :: data(21)
+    real, pointer    :: result(:,:,:,:)
+    complex, pointer :: temp(:,:)
+    result(i:i,j:j,1:4,1:5) => data(2:)%re
+    temp(1:4,1:5)           => data(1:20)
+    result(i,j,:,:) = abs(temp)
+  end subroutine test
+end program main
+
+! PR fortran/113928
+!
+! Contributed by < eddyg_61-bugzilla at yahoo dot it >
+
+subroutine pr113928
+  implicit none
+  integer, parameter :: N = 4
+  complex, target    :: wz(N) = 0.
+  real,    pointer   :: wr(:)
+  integer :: i
+
+  wr => wz%re
+  wr = [(i,i=1,N)]
+  wr = wr + wz(N:1:-1)%re
+! print *, wr
+  if (any (wr /= N+1)) stop 3
+end

Reply via email to