trans-array.c (gfc_walk_elemental_function_args): Don't skip the advance to the next...
authorMikael Morin <mikael@gcc.gnu.org>
Fri, 8 May 2015 14:53:20 +0000 (14:53 +0000)
committerMikael Morin <mikael@gcc.gnu.org>
Fri, 8 May 2015 14:53:20 +0000 (14:53 +0000)
gcc/fortran/
* trans-array.c (gfc_walk_elemental_function_args):
Don't skip the advance to the next dummy argument when skipping
absent optional args.
gcc/testsuite/
* gfortran.dg/elemental_optional_args_7.f90: New.

From-SVN: r222913

gcc/fortran/ChangeLog
gcc/fortran/trans-array.c
gcc/testsuite/ChangeLog
gcc/testsuite/gfortran.dg/elemental_optional_args_7.f90 [new file with mode: 0644]

index 67f9e097e47b86b0d38637a4756490a472c607c0..1091b187d060d21b4f59d5c528fe90366162ebce 100644 (file)
@@ -1,3 +1,9 @@
+2015-05-08  Mikael Morin  <mikael@gcc.gnu.org>
+
+       * trans-array.c (gfc_walk_elemental_function_args):
+       Don't skip the advance to the next dummy argument when skipping
+       absent optional args.
+
 2015-05-05  David Malcolm  <dmalcolm@redhat.com>
 
        * expr.c (check_inquiry): Fix indentation so that it reflects the
index a17f4314d47c0119fc59b674063edb753848e78b..00334b131918fbd3d1d346ab0274ee36bdc9bba4 100644 (file)
@@ -9092,7 +9092,7 @@ gfc_walk_elemental_function_args (gfc_ss * ss, gfc_actual_arglist *arg,
   for (; arg; arg = arg->next)
     {
       if (!arg->expr || arg->expr->expr_type == EXPR_NULL)
-       continue;
+       goto loop_continue;
 
       newss = gfc_walk_subexpr (head, arg->expr);
       if (newss == head)
@@ -9122,6 +9122,7 @@ gfc_walk_elemental_function_args (gfc_ss * ss, gfc_actual_arglist *arg,
             tail = tail->next;
         }
 
+loop_continue:
       if (dummy_arg != NULL)
        dummy_arg = dummy_arg->next;
     }
index e71b8e043d71c1b203616c3f052fe9979d5814f6..c904070b6ac64662da59b83c0d339acbc4a9fce4 100644 (file)
@@ -1,3 +1,7 @@
+2015-05-08  Mikael Morin  <mikael@gcc.gnu.org>
+
+       * gfortran.dg/elemental_optional_args_7.f90: New.
+
 2015-05-08  Alan Lawrence  <alan.lawrence@arm.com>
 
        * gcc.target/aarch64/singleton_intrinsics_1.c: Generalize regex to
diff --git a/gcc/testsuite/gfortran.dg/elemental_optional_args_7.f90 b/gcc/testsuite/gfortran.dg/elemental_optional_args_7.f90
new file mode 100644 (file)
index 0000000..8d366c3
--- /dev/null
@@ -0,0 +1,37 @@
+! { dg-do run }
+!
+! The handling of scalar optional arguments passed to elemental procedure
+! did not keep actual arguments and dummy arguments synchronized while
+! walking them in gfc_walk_elemental_function_args, leading to a
+! null pointer dereference in the generated code.
+!
+  implicit none
+
+  integer, parameter :: n = 3
+
+  call do_test
+
+contains
+
+  elemental function five(nonopt1, opt1, nonopt2, opt2)
+    integer, intent(in), optional :: opt1, opt2
+    integer, intent(in) :: nonopt1, nonopt2
+    integer :: five
+
+    if (.not. present(opt1) .and. .not. present(opt2)) then
+      five = 5
+    else
+      five = -7
+    end if
+  end function five
+
+  subroutine do_test(opt)
+    integer, optional :: opt
+    integer :: i = -1, a(n) = (/ (i, i=1,n) /)
+    integer :: b(n)
+
+    b = five(a, nonopt2=i, opt2=opt)
+    if (any(b /= 5)) call abort
+  end subroutine do_test
+
+end