This is the mail archive of the gcc-bugs@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]

[Bug fortran/68993] MERGE does not evaluate its arguments


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.

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