I have a crashing bug that only occurs in the release version of my code, and requires the optimisation level to be 'Optimise for speed' or greater. The symptom is that an array gets written beyond its end, but this is in turn caused by a block of code inside a loop that should reset a counter back to zero failing to execute.
Unfortunately, putting in diagnostic write statements mostly makes the symptom disappear.
My guess is that either there is a problem with the optimising compiler itself, or that somewhere my code is corrupting a byte or two of memory and that any changes I make to my code (e.g. putting in diagnostics) moves the code around and removes the symptoms.
The code itself is very big and I can't reproduce the problem in anything shorter. I can only give an outline here:
do i = 1, iNum_type_output
write(*, *) '***** diagnostic 1'
if () then
thisFunctionName = iRetrainReturnCode
write(*, *) '***** diagnostic 2'
write(*, *) '***** diagnostic 3'
Inserting diagnostic 2 does not alter the execution. If diagnostic 2 is the only write statement, then the output shows that the loop (or at least that write statement) does not execute. The array index does not get reset, and I get a crash as I do without any write statements. When I put in either diagnostic 1 or diagnostic 3, then the behaviour changes, the loop gets executed properly and the program doesn't crash.
From the function return value, I know that it never returns prematurely from the return statement in the loop (i.e. the doesn't occur). Confirming this, the code placed after the loop always gets executed. By examining the value of i, the loop counter, I can see that it is initialised to 1 by the do statement, but is not incremented. I also tried replacing the return statement above with a write statement. The write statement never executed, and the program appeared to run normally (without the other diagnostic write statements being necessary).
Putting in various write statements before the loop also makes the symptom disappear. In fact, almost any change to any of the code in the loop or before it makes the symptom disappear. Selecting array bounds checking makes the symptom disappear (but doesn't report any array bounds violations).
I am now at a complete loss. Every time I do something to try to get more diagnostic information, the symptom disappears. Can anyone suggest anything? In particular, how can I find out whether the problem is my code or the compiler optimisations? If it is my code, then reducing the level of compiler optimisations is probably just moving the error to somewhere where it is less obvious.
All suggestions gratefully received.