From: Mikael Morin Date: Fri, 7 Aug 2015 09:55:36 +0000 (+0000) Subject: Fix elemental wrong-code X-Git-Tag: releases/gcc-4.9.4~656 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=bce1111b19685b5139ed3a5dd739357026ca4183;p=thirdparty%2Fgcc.git Fix elemental wrong-code PR fortran/66929 gcc/fortran/ * trans-array.c (gfc_get_proc_ifc_for_expr): Use esym as procedure symbol if available. gcc/testsuite/ * gfortran.dg/generic_30.f90: New. * gfortran.dg/generic_31.f90: New. From-SVN: r226718 --- diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index 34d612441156..4398d805e590 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,9 @@ +2015-08-07 Mikael Morin + + PR fortran/66929 + * trans-array.c (gfc_get_proc_ifc_for_expr): Use esym as procedure + symbol if available. + 2015-08-05 Mikael Morin PR fortran/64921 diff --git a/gcc/fortran/trans-array.c b/gcc/fortran/trans-array.c index 8e5bea1917af..877e37109a9b 100644 --- a/gcc/fortran/trans-array.c +++ b/gcc/fortran/trans-array.c @@ -8925,7 +8925,11 @@ gfc_get_proc_ifc_for_expr (gfc_expr *procedure_ref) return NULL; /* Normal procedure case. */ - sym = procedure_ref->symtree->n.sym; + if (procedure_ref->expr_type == EXPR_FUNCTION + && procedure_ref->value.function.esym) + sym = procedure_ref->value.function.esym; + else + sym = procedure_ref->symtree->n.sym; /* Typebound procedure case. */ for (ref = procedure_ref->ref; ref; ref = ref->next) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index c69841a296f5..b9213d2ad34a 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2015-08-07 Mikael Morin + + PR fortran/66929 + * gfortran.dg/generic_30.f90: New. + * gfortran.dg/generic_31.f90: New. + 2015-08-05 Mikael Morin PR fortran/64921 diff --git a/gcc/testsuite/gfortran.dg/generic_30.f90 b/gcc/testsuite/gfortran.dg/generic_30.f90 new file mode 100644 index 000000000000..5f82373cfb71 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/generic_30.f90 @@ -0,0 +1,41 @@ +! { dg-do compile } +! +! PR fortran/66929 +! Generic procedures as actual argument used to lead to +! a NULL pointer dereference in gfc_get_proc_ifc_for_expr +! because the generic symbol was used as procedure symbol, +! instead of the specific one. + +module iso_varying_string + type, public :: varying_string + character(LEN=1), dimension(:), allocatable :: chars + end type varying_string + interface operator(/=) + module procedure op_ne_VS_CH + end interface operator (/=) + interface trim + module procedure trim_ + end interface +contains + elemental function op_ne_VS_CH (string_a, string_b) result (op_ne) + type(varying_string), intent(in) :: string_a + character(LEN=*), intent(in) :: string_b + logical :: op_ne + op_ne = .true. + end function op_ne_VS_CH + elemental function trim_ (string) result (trim_string) + type(varying_string), intent(in) :: string + type(varying_string) :: trim_string + trim_string = varying_string(["t", "r", "i", "m", "m", "e", "d"]) + end function trim_ +end module iso_varying_string +module syntax_rules + use iso_varying_string, string_t => varying_string +contains + subroutine set_rule_type_and_key + type(string_t) :: key + if (trim (key) /= "") then + print *, "non-empty" + end if + end subroutine set_rule_type_and_key +end module syntax_rules diff --git a/gcc/testsuite/gfortran.dg/generic_31.f90 b/gcc/testsuite/gfortran.dg/generic_31.f90 new file mode 100644 index 000000000000..2c0d0299005c --- /dev/null +++ b/gcc/testsuite/gfortran.dg/generic_31.f90 @@ -0,0 +1,35 @@ +! { dg-do run } +! +! PR fortran/66929 +! Check that the specific FIRST symbol is used for the call to FOO, +! so that the J argument is not assumed to be present + +module m + interface foo + module procedure first + end interface foo +contains + elemental function bar(j) result(r) + integer, intent(in), optional :: j + integer :: r, s(2) + ! We used to have NULL dereference here, in case of a missing J argument + s = foo(j, [3, 7]) + r = sum(s) + end function bar + elemental function first(i, j) result(r) + integer, intent(in), optional :: i + integer, intent(in) :: j + integer :: r + if (present(i)) then + r = i + else + r = -5 + end if + end function first +end module m +program p + use m + integer :: i + i = bar() + if (i /= -10) call abort +end program p