Attached a small example where an elemental function returns the incorrect result when called with a scalar argument. This is with the 14.0.2 compiler.
Thank you Neil. I'll try reproducing this and also try with our current Beta 15.0 and keep you posted.
Thank you for the wonderful test case! I reproduced the incorrect results with both the 14.0 and 15.0 Beta compilers and directed the defect to Development (see internal tracking id below) for correcting. I'll keep your post updated with status as I learn it.
(Internal tracking id: DPD200253312)
Ask yourself when/what deallocates the string in:
print *, elem_raise_case(string()), ' (expect "XXXXX")' ! GIVES WRONG RESULT
From my understanding of the rules, as written, the deallocation will occur on exit from string() function,
Try adding INTENT(OUT) to the attribute of string (inside string()).
Edit - and ucs in elemental functon
There is still an issue of at what point is the string deallocated (if deallocated at all).
It should work the way it is written. I have a pretty good guess as to what is going wrong. One isn't allowed to say INTENT(OUT) on the function result so that won't help. The problem is outside string, I am 99.9% certain.
>>It should work the way it is written.
Where would the (implicit) deallocation occur?
a) return from string() in which case the result is located in "freed" memory and may or may not contain the residuals of what it was initialized to.
b) At expression end within () of elem_raise_case
c) At expression end at argument evaluation in print (between the ,'s)
d) At statement end (after print)
e) At program end (or subroutine had this code resided within subroutine)
f) Never (until program termination). IOW would this generate a memory leak?
F2008 18.104.22.168 tells us that it is deallocated "after execution of the innermost executable construct containing the reference." In this case, the statement with the function reference is the innermost executable construct.
You should be able to tell using an allocatable function result that is of a derived type with an appropriate finalizer - the finalizer gets called before the result is deallocated.
And how would you expect to tell where the finalizer was called in:
There are three (or more) potential places (four if you include exiting the routine containing the print, though that would occur after the statement following the print).
The finalizer would be called when the value is deallocated. It could be after elem_raise_case returns or after the PRINT completes. Given that elem_raise_case is elemental I would expect the value to be deallocated after each call to elem_raise_case.
>>Given that elem_raise_case is elemental I would expect the value to be deallocated after each call to elem_raise_case.
Which could potentially result (in this example) in one of the other expressions/arguments on the print statement in clobbering the memory where the result happened to reside.
Out of curiosity, what happens when you swap the args on the print statement?
print *,' (expect "XXXXX")', elem_raise_case(string())
Why do you think that, Jim? The value of the string call is done with by the time elem_raise_case returns. If string returned an array, the compiler would construct a loop that calls elem_raise_case for each element in the array, putting the result in a temporary that is then printed.