https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68993
kargl at gcc dot gnu.org changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |kargl at gcc dot gnu.org --- Comment #1 from kargl at gcc dot gnu.org --- (In reply to Joost VandeVondele from comment #0) > I'm not 100% sure what the right answer is, i.e. if MERGE is defined by the > standard to do something special with respect to evaluating its arguments. > The origin is code like this: > > MERGE(C_NULL_PTR, C_LOC(pc), .NOT.PRESENT(pc))) > > is this standard conforming if pc is not present ? In that case MERGE is > supposed to return C_NULL_PTR, but I see no reason why C_LOC(pc) would not > be evaluated first. The above is using C binding features. Your example below has nothing to do with C binding. However, ... > > Gfortran and ifort behave differently in this respect.In the below code > ifort calls foo 4x while gfortran calls it 2x. both results are plausible as the code is invalid. 7.1.8.1 Evaluation of operands It is not necessary for a processor to evaluate all of the operands of an expression, or to evaluate entirely each operand, if the value of the expression can be determined otherwise. If a statement contains a function reference in a part of an expression that need not be evaluated, all entities that would have become defined in the execution of that reference become undefined at the completion of evaluation of the expression containing the function reference. C.4.2 Evaluation of function references If more than one function reference appears in a statement, they may be executed in any order (subject to a function result being evaluated after the evaluation of its arguments) and their values shall not depend on the order of execution. This lack of dependence on order of evaluation permits parallel execution of the function references (7.1.8.1). C.9.5 Argument association and evaluation (12.4.1.2) The provisions for expression evaluation give the processor considerable flexibility for obtaining expression values in the most efficient way possible. This includes not evaluating or only partially evaluating an operand, for example, if the value of the expression can be determined otherwise (7.1.8.1). This flexibility applies to function argument evaluation, including the order of argument evaluation, delaying argument evaluation, and omitting argument evaluation. A processor may delay the evaluation of an argument in a procedure reference until the execution of the procedure refers to the value of that argument, provided delaying the evaluation of the argument does not otherwise affect the results of the program. The processor may, with similar restrictions, entirely omit the evaluation of an argument not referenced in the execution of the procedure. This gives processors latitude for optimization (for example, for parallel processing). > While gfortran's way of doing things seem natural, I suspect it is not > standard conforming. gfortran can do whatever it wants here as the code is invalid. > > cat test.f90 > MODULE test > INTEGER, SAVE :: i=0 > CONTAINS > INTEGER FUNCTION foo() > i=i+1 > foo=i > END FUNCTION > END MODULE test > > USE test > WRITE(6,*) MERGE(foo(),foo(),.FALSE.) Does the evaluation of foo() in the above give merge(1, 2, .false.) or merge(2, 1,.false.)? Or, given that the 3rd argument is .false., gfortran replaced merge() with foo(). So, your code transforms to write(6,*) foo() write(6,*) foo() > WRITE(6,*) MERGE(foo(),foo(),.FALSE.) > WRITE(6,*) i > END I believe that this PR should be closed with INVALID.