re PR fortran/56649 (ICE gfc_conv_structure with MERGE)
authorTobias Burnus <burnus@net-b.de>
Tue, 26 Mar 2013 14:51:56 +0000 (15:51 +0100)
committerTobias Burnus <burnus@gcc.gnu.org>
Tue, 26 Mar 2013 14:51:56 +0000 (15:51 +0100)
2013-03-26  Tobias Burnus  <burnus@net-b.de>

        PR fortran/56649
        * simplify.c (gfc_simplify_merge): Simplify more.

2013-03-26  Tobias Burnus  <burnus@net-b.de>

        PR fortran/56649
        * gfortran.dg/merge_init_expr_2.f90: New.
        * gfortran.dg/merge_char_1.f90: Modify test to
        stay a run-time test.
        * gfortran.dg/merge_char_3.f90: Ditto.

From-SVN: r197109

gcc/fortran/ChangeLog
gcc/fortran/simplify.c
gcc/testsuite/ChangeLog
gcc/testsuite/gfortran.dg/merge_char_1.f90
gcc/testsuite/gfortran.dg/merge_char_3.f90
gcc/testsuite/gfortran.dg/merge_init_expr_2.f90 [new file with mode: 0644]

index a14423cc94c6ca110fa2a3d1d30fcd3a8352722b..e11523cfad67389c20fb6a273c1637dd20690a01 100644 (file)
@@ -1,3 +1,8 @@
+2013-03-26  Tobias Burnus  <burnus@net-b.de>
+
+       PR fortran/56649
+       * simplify.c (gfc_simplify_merge): Simplify more.
+
 2013-03-25  Tobias Burnus  <burnus@net-b.de>
 
        PR fortran/38536
index a0909a38349a7ccd7b7d288c45a19331917eaa7c..dc5dad294aab88c5d56833d25a95bb927693c6d9 100644 (file)
@@ -3976,12 +3976,47 @@ gfc_simplify_maskl (gfc_expr *i, gfc_expr *kind_arg)
 gfc_expr *
 gfc_simplify_merge (gfc_expr *tsource, gfc_expr *fsource, gfc_expr *mask)
 {
-  if (tsource->expr_type != EXPR_CONSTANT
-      || fsource->expr_type != EXPR_CONSTANT
-      || mask->expr_type != EXPR_CONSTANT)
+  gfc_expr * result;
+  gfc_constructor *tsource_ctor, *fsource_ctor, *mask_ctor;
+
+  if (mask->expr_type == EXPR_CONSTANT)
+    return gfc_get_parentheses (gfc_copy_expr (mask->value.logical
+                                              ? tsource : fsource));
+
+  if (!mask->rank || !is_constant_array_expr (mask)
+      || !is_constant_array_expr (tsource) || !is_constant_array_expr (fsource))
     return NULL;
 
-  return gfc_copy_expr (mask->value.logical ? tsource : fsource);
+  result = gfc_get_array_expr (tsource->ts.type, tsource->ts.kind,
+                              &tsource->where);
+  if (tsource->ts.type == BT_DERIVED)
+    result->ts.u.derived = tsource->ts.u.derived;
+  else if (tsource->ts.type == BT_CHARACTER)
+    result->ts.u.cl = tsource->ts.u.cl;
+
+  tsource_ctor = gfc_constructor_first (tsource->value.constructor);
+  fsource_ctor = gfc_constructor_first (fsource->value.constructor);
+  mask_ctor = gfc_constructor_first (mask->value.constructor);
+
+  while (mask_ctor)
+    {
+      if (mask_ctor->expr->value.logical)
+       gfc_constructor_append_expr (&result->value.constructor,
+                                    gfc_copy_expr (tsource_ctor->expr),
+                                    NULL);
+      else
+       gfc_constructor_append_expr (&result->value.constructor,
+                                    gfc_copy_expr (fsource_ctor->expr),
+                                    NULL);
+      tsource_ctor = gfc_constructor_next (tsource_ctor);
+      fsource_ctor = gfc_constructor_next (fsource_ctor);
+      mask_ctor = gfc_constructor_next (mask_ctor);
+    }
+
+  result->shape = gfc_get_shape (1);
+  gfc_array_size (result, &result->shape[0]);
+
+  return result;
 }
 
 
index 52a1a8d38d79936748b2bd4a459f31d99e5be72a..c1117941e631fd403191c928b2b30f9e11de0e57 100644 (file)
@@ -1,3 +1,11 @@
+2013-03-26  Tobias Burnus  <burnus@net-b.de>
+
+       PR fortran/56649
+       * gfortran.dg/merge_init_expr_2.f90: New.
+       * gfortran.dg/merge_char_1.f90: Modify test to
+       stay a run-time test.
+       * gfortran.dg/merge_char_3.f90: Ditto.
+
 2013-03-26  Paolo Carlini  <paolo.carlini@oracle.com>
 
        * g++.dg/cpp0x/constexpr-friend-2.C: New.
index 5974e8c06c389387cdaa230d60717b104675d57f..ece939eea06d36ac5bc8481665c260d8c9e5bc71 100644 (file)
@@ -4,6 +4,13 @@
 ! PR 15327
 ! The merge intrinsic didn't work for strings
 character*2 :: c(2)
+logical :: ll(2)
+
+ll = (/ .TRUE., .FALSE. /)
+c = merge( (/ "AA", "BB" /), (/ "CC", "DD" /), ll )
+if (c(1).ne."AA" .or. c(2).ne."DD") call abort ()
+
+c = ""
 c = merge( (/ "AA", "BB" /), (/ "CC", "DD" /), (/ .TRUE., .FALSE. /) )
 if (c(1).ne."AA" .or. c(2).ne."DD") call abort ()
 end
index 498e3ec73c54dc3e0ad35a7cb628fa0546fd6a66..114214136e21b50d12952057581adc9e1a1797af 100644 (file)
@@ -12,7 +12,8 @@ subroutine foo(a)
 implicit none
 character(len=*) :: a
 character(len=3) :: b
-print *, merge(a,b,.true.)  ! Unequal character lengths
+logical :: ll = .true.
+print *, merge(a,b,ll)  ! Unequal character lengths
 end subroutine foo
 
 call foo("ab")
diff --git a/gcc/testsuite/gfortran.dg/merge_init_expr_2.f90 b/gcc/testsuite/gfortran.dg/merge_init_expr_2.f90
new file mode 100644 (file)
index 0000000..9b20310
--- /dev/null
@@ -0,0 +1,58 @@
+! { dg-do compile }
+! { dg-options "-fdump-tree-original" }
+!
+! PR fortran/56649
+! MERGE was not properly compile-time simplified
+!
+! Contributed by Bill Long
+!
+module m
+  implicit none
+
+  integer, parameter :: int32 = 4
+  type MPI_Datatype
+    integer :: i
+  end type MPI_Datatype
+
+  integer,private,parameter :: dik = kind(0)
+  type(MPI_Datatype),parameter,private :: MPIx_I4 = MPI_Datatype( 1275069467)
+  type(MPI_Datatype),parameter,private :: MPIx_I8 = MPI_Datatype( 1275070491)
+  type(MPI_Datatype),parameter :: MPI_INTEGER = merge(MPIx_I4, MPIx_I8, &
+                                                      dik==int32)
+contains
+  subroutine foo
+    integer :: check1
+    check1 = MPI_INTEGER%i
+  end subroutine foo
+end module m
+
+module m2
+  implicit none
+  integer, parameter :: int32 = 4
+  type MPI_Datatype
+    integer :: i
+  end type MPI_Datatype
+
+  integer,private,parameter :: dik = kind(0)
+  type(MPI_Datatype),parameter,private :: MPIx_I4 = MPI_Datatype( 1275069467)
+  type(MPI_Datatype),parameter,private :: MPIx_I8 = MPI_Datatype( 1275070491)
+  type(MPI_Datatype),parameter :: MPI_INTEGER(1) = merge([MPIx_I4], [MPIx_I8], &
+                                                      [dik==int32])
+contains
+  subroutine foo
+    logical :: check2
+    check2 = MPI_INTEGER(1)%i == 1275069467
+  end subroutine foo
+end module m2
+
+
+subroutine test
+  character(len=3) :: one, two, three
+  logical, parameter :: true = .true.
+  three = merge (one, two, true)
+end subroutine test
+
+! { dg-final { scan-tree-dump-times "check1 = 1275069467;" 1 "original" } }
+! { dg-final { scan-tree-dump-times "check2 = 1;" 1 "original" } }
+! { dg-final { scan-tree-dump-times "__builtin_memmove ..void .. &three, .void .. &one, 3.;" 1 "original" } }
+! { dg-final { cleanup-tree-dump "original" } }