On Thu, Jun 14, 2018 at 11:55:45AM +0200, Jakub Jelinek wrote: > > I bet gfortran evaluates the side-effects left-to-right and evaluates both > arguments always, right? >
Currently, gfortran evaluates a logical expression left-to-right due to its use of the middle-end's TRUTH_AND_EXPR. The Fortran standard does not require this left-to-right evaluation. Janus found that with '.false. .and. check()' gfortran will not evaluate check(). This is a valid Fortran optimization in that '.false.' and '.false. .and. check()' are equivalent expessions no matter what the return value of check() is. It does not matter if check() is PURE or IMPURE. He then found with the operands reversed that check() is evaluated. He traced this behavior to TRUTH_AND_EXPR, where C allows short-circuiting and it performs left-to-right evaluation. I've already provided a sloppy patch in comment #33 of PR85599 that forces gfortran to evaluate both operands. The patch is equivalent to writing tmp1 = .false. tmp2 = check() if (tmp1 .and. tmp2) ... The patch is sloppy because this forced evaulation should be enabled by -fno-short-circuit (or some such option). Thomas' patch with a warning is simply meant to help programmers who aren't familiar with the Fortran standard. He's trying to use PUREness as a way to surpress the warning. A PURE function by design does not have side-effects so eliminating the evaluation of PURE function should be okay. An IMPURE function or an unmarked function may or may not have side effects. The moral of the story: Don't use functions with side-effects. -- Steve