This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [Patch, Fortran] PR 85599: warn about short-circuiting of logical expressions for non-pure functions


Just noticed another problematic case: Calls to generic interfaces are
not detected as implicitly pure, see enhanced test case in attachment.
Will look into this problem on the weekend ...

Cheers,
Janus

2018-07-12 21:43 GMT+02:00 Janus Weil <janus@gcc.gnu.org>:
> Hi all,
>
> here is a minor update of the patch, which cures some problems with
> implicitly pure functions in the previous version.
>
> Most implicitly pure functions were actually detected correctly, but
> implicitly pure functions that called other implicitly pure functions
> were not detected properly, and therefore could trigger a warning.
> This is fixed in the current version, which still regtests cleanly
> (note that alloc-comp-3.f90 currently fails due to PR 86417). The test
> case is also enhanced to include the problematic case.
>
> Ok for trunk?
>
> Cheers,
> Janus
>
>
>
> 2018-07-11 23:06 GMT+02:00 Janus Weil <janus@gcc.gnu.org>:
>> Hi all,
>>
>> after the dust of the heated discussion around this PR has settled a
>> bit, here is another attempt to implement at least some basic warnings
>> about compiler-dependent behavior concerning the short-circuiting of
>> logical expressions.
>>
>> As a reminder (and recap of the previous discussion), the Fortran
>> standard unfortunately is a bit sloppy in this area: It allows
>> compilers to short-circuit the second operand of .AND. / .OR.
>> operators, but does not require this. As a result, compilers can do
>> what they want without conflicting with the standard, and they do:
>> gfortran does short-circuiting (via TRUTH_ANDIF_EXPR/TRUTH_ORIF_EXPR),
>> ifort does not.
>>
>> I'm continuing here the least-invasive approach of keeping gfortran's
>> current behavior, but warning about cases where compilers may produce
>> different results.
>>
>> The attached patch is very close to the version I posted previously
>> (which was already approved by Janne), with the difference that the
>> warnings are now triggered by -Wextra and not -Wsurprising (which is
>> included in -Wall), as suggested by Nick Maclaren. I think this is
>> more reasonable, since not everyone may want to see these warnings.
>>
>> Note that I don't want to warn about all possible optimizations that
>> might be allowed by the standard, but only about those that are
>> actually problematic in practice and result in compiler-dependent
>> behavior.
>>
>> The patch regtests cleanly on x86_64-linux-gnu. Ok for trunk?
>>
>> Cheers,
>> Janus
>>
>>
>> 2018-07-11  Thomas Koenig  <tkoenig@gcc.gnu.org>
>>         Janus Weil  <janus@gcc.gnu.org>
>>
>>         PR fortran/85599
>>         * dump-parse-tree (show_attr): Add handling of implicit_pure.
>>         * resolve.c (impure_function_callback): New function.
>>         (resolve_operator): Call it vial gfc_expr_walker.
>>
>>
>> 2018-07-11  Janus Weil  <janus@gcc.gnu.org>
>>
>>         PR fortran/85599
>>         * gfortran.dg/short_circuiting.f90: New test.
! { dg-do compile }
! { dg-additional-options "-Wextra" }
!
! PR 85599: warn about short-circuiting of logical expressions for non-pure functions
!
! Contributed by Janus Weil <janus@gcc.gnu.org>

module a

   interface impl_pure_a
      module procedure impl_pure_a1
   end interface

contains

    logical function impl_pure_a1()
      impl_pure_a1 = .true.
   end function

end module


program short_circuit

   use a

   logical :: flag
   flag = .false.
   flag = check() .and. flag
   flag = flag .and. check()        ! { dg-warning "might not be evaluated" }
   flag = flag .and. pure_check()
   flag = flag .and. impl_pure_1()
   flag = flag .and. impl_pure_2()
   flag = flag .and. impl_pure_a1()
   flag = flag .and. impl_pure_a()  ! bogus warning here

contains

   logical function check()
      integer, save :: i = 1
      print *, "check", i
      i = i + 1
      check = .true.
   end function

   logical pure function pure_check()
      pure_check = .true.
   end function

   logical function impl_pure_1()
      impl_pure_1 = .true.
   end function

   logical function impl_pure_2()
      impl_pure_2 = impl_pure_1()
   end function


end

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]