From: mecej4 on
Richard Maine wrote:

> Gordon Sande <Gordon.Sande(a)gmail.com> wrote:
>
>> There are various "definitions" of undefined. Many are so watered down
>> that it takes a skilled lawyer to show why they are not fraudulent. If
>> you don't notice the distinctions you can be fooled into treating them as
>> all the same.
>>
>> The useful definition is that the variable has never been assigned a
>> value by the user after the variable has come into existence.
>
> There is also the definition in the Fortran standard. That one probably
> falls into the category of taking a skilled lawyer, but it is one that
> is particularly relevant to Fortran. Note that it is not particularly
> close to the same definition as the one you refer to above as "the
> useful definition." For example, the f2003 standard lists 18 ways for a
> variable to become undefined, and some of those 18 ways include multiple
> subitems, so that the list might plausibly said to have about 30 ways.
>
> Yes, it takes a language lawyer to read some of them, but others are
> pretty important and useful to know. People get bit by several of them,
> sometimes even when the people do know the rules and violate them by
> accident. That's happened to me. I'm thinking of a case where I
> accidentally declared a dummy argument to be intent(out), which made the
> actual argument become undefined, even if it had been previously
> defined. That code worked for several years until a new version of the
> compiler behaved differently from the version I had been using.
>
One case that I tripped over is the following. I had an array argument to a
subroutine. This argument, depending on the values of other arguments,
might be left untouched or have a few elements updated.

The expectation was that those elements that were not updated would retain
their previous values, an expectation that emanated from the principle
of "do no harm" and Fortran 77 experience. However, Fortran 9X rules state
that INTENT(OUT) arguments become undefined at subroutine entry.

Similarly, if an argument of derived type is passed as an INTENT(OUT)
argument, one must make sure to redefine _every_ component of it. The old
F77 way of allocating an array on the generous side, and using only a part
of it most of the time, does not work with INTENT(OUT). What is worse,
since few compilers enforce this rule, so I had created a bug that lay
dormant for a long time until my program met a compiler that applied the
rule.

-- mecej4
From: steve on
On May 26, 11:55 am, JB <f...(a)bar.invalid> wrote:
> On 2010-05-26, Gordon Sande <Gordon.Sa...(a)gmail.com> wrote:
>
>
>
> > On 2010-05-26 11:50:56 -0300, JB <f...(a)bar.invalid> said:
>
> >> On 2010-05-26, Gordon Sande <Gordon.Sa...(a)gmail.com> wrote:
> >>> The useful definition is that the variable has never been assigned a value
> >>> by the user after the variable has come into existence. The descriptions
> >>> of Valgrind I have seen to not include such a capability.
>
> >> Would you say that the following example constitutes detection of an
> >> uninitialized variable, or what is it?
>
> >> program vt
> >>   integer :: ii
> >>   print *, ii
> >> end program vt
>
> >> $ valgrind --track-origins=yes ./a.out
> >> ==27324== Memcheck, a memory error detector
> >> ==27324== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al.
> >> ==27324== Using Valgrind-3.5.0 and LibVEX; rerun with -h for copyright info
> >> ==27324== Command: ./a.out
> >> ==27324==
> >> ==27324== Conditional jump or move depends on uninitialised value(s)
> >> ==27324==    at 0x4C526F5: ??? (in /usr/lib64/libgfortran.so.3.0.0)
> >> ==27324==    by 0x4CFD144: ??? (in /usr/lib64/libgfortran.so.3.0.0)
> >> ==27324==    by 0x4D006DE: ??? (in /usr/lib64/libgfortran.so.3.0.0)
> >> ==27324==    by 0x40076B: MAIN__ (vt.f90:3)
> >> ==27324==    by 0x4007A9: main (in /home/job/src/valgrindtest/a.out)
> >> ==27324==  Uninitialised value was created by a stack allocation
> >> ==27324==    at 0x400711: MAIN__ (vt.f90:1)
> >> ...
>
> >> valgrind is not that good at detecting stack allocations; as you can
> >> see, it only gives the line where the procedure starts, not which
> >> variable is guilty. Heap detection is generally better, and usually at
> >> least, gives directly the line where the error occurs and where the
> >> variable was declared. (The ???'s are because for some reason
> >> libgfortran was not compiled with debug symbols included)
>
> >> And, as I mentioned in my previous message, if the ii variable is made
> >> SAVE, then valgrind won't detect it, as the compiler sets it to 0, and
> >> valgrind in it's somewhat C-centric worldview thinks everything is ok.
>
> > A rather watered down defintion of detecting an undefined variable.
>
> How come? You yourself provided a defition for detecting undefined
> variables as "The useful definition is that the variable has never
> been assigned a value by the user after the variable has come into
> existence". Then you claimed that valgrind cannot detect such errors
> "The descriptions of Valgrind I have seen to not include such a
> capability.". And then I provided a trivial counterexample where
> valgrind was indeed able to detect such a use of an undefined
> variable.
>
> Seems like you're trying to sucker me into a game of moving the
> goalposts.
>
> > Simple
> > flow analysis yields this as an uninitialized variable for many compilers.
>
> Yes. What does that have to do with valgrind?
>
> > Are you sure you didn't take at least first year law school
>
> No, I didn't. I once had a girlfriend who was studying law, though, in
> case you feel that's somehow pertinent to the argument.
>
> > if that is
> > your example of useful undefined variable checking? ;-)
>
> Well, the example wasn't intented to show the limits of what valgrind
> is capable of, just that contrary to previous claims, it can indeed
> detect use of uninitialized variables.
>
> I have successfully used valgrind to find uses of uninitialized
> variables, and other common memory errors that I myself, and others,
> have made, so yes, I find it useful, despite it perhaps never
> fulfilling some yet to be heard criteria for perfection.
>
> > Try something like setting the 1st and 3rd element of an array and referecing
> > the 2nd element. And make these subscript values data values so there
> > can be no static analysis. The systems I gave (but you snipped) all will find
> > that the 2nd element is undefined.
>
> I sort of fear that a testcase I do myself will, like my previous one,
> not be up to your high standards, so why don't you provide the code
> that I can test since you already seem to have it?
>

laptop:kargl[215] gfc4x -o z k.f90
laptop:kargl[216] valgrind ./z
==23180== Memcheck, a memory error detector
==23180== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et
al.
==23180== Using Valgrind-3.5.0 and LibVEX; rerun with -h for copyright
info
==23180== Command: ./z
==23180==
2
==23180==
==23180== HEAP SUMMARY:
==23180== in use at exit: 0 bytes in 0 blocks
==23180== total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==23180==
==23180== All heap blocks were freed -- no leaks are possible
==23180==
==23180== For counts of detected and suppressed errors, rerun with: -v
==23180== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from
0)
laptop:kargl[217] cat k.f90
program gordon
integer i(3)
i(1) = 1
i(2) = 2
i(3) = 3
print *, i(2)
end program gordon

After editing k.f90 to remove the i(2) assignment:

k.f90: 7 lines, 92 characters.
laptop:kargl[219] cat k.f90
program gordon
integer i(3)
i(1) = 1
i(3) = 3
print *, i(2)
end program gordon

laptop:kargl[220] gfc4x -o z k.f90
laptop:kargl[221] valgrind ./z
==23190== Memcheck, a memory error detector
==23190== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et
al.
==23190== Using Valgrind-3.5.0 and LibVEX; rerun with -h for copyright
info
==23190== Command: ./z
==23190==
==23190== Conditional jump or move depends on uninitialised value(s)
==23190== at 0x8050ED4: gfc_itoa (write.c:917)
==23190== by 0x8050FB6: write_integer (write.c:1103)
==23190== by 0x805377C: _gfortrani_list_formatted_write (write.c:
1350)
==23190== by 0x80497C7: _gfortran_transfer_integer (transfer.c:
1779)
==23190== by 0x8048254: MAIN__ (in /usr/home/kargl/tmp/z)
==23190== by 0x80482A5: main (in /usr/home/kargl/tmp/z)

There are 6 such blocks spewed by valgrind followed by


==23190==
==23190== Syscall param write(buf) points to uninitialised byte(s)
==23190== at 0x80862BF: __sys_write (in /usr/home/kargl/tmp/z)
==23190== by 0x8053A27: _gfortrani_fbuf_flush (unix.h:54)
==23190== by 0x804A524: _gfortrani_next_record (transfer.c:3224)
==23190== by 0x804AC0B: finalize_transfer (transfer.c:3319)
==23190== by 0x804AD68: _gfortran_st_write_done (transfer.c:3427)
==23190== by 0x8048266: MAIN__ (in /usr/home/kargl/tmp/z)
==23190== by 0x80482A5: main (in /usr/home/kargl/tmp/z)
==23190== Address 0x40e402 is not stack'd, malloc'd or (recently)
free'd

Need to move the goal post a little further left.

:-)

--
steve
From: Gordon Sande on
On 2010-05-26 16:12:35 -0300, nospam(a)see.signature (Richard Maine) said:

> Gordon Sande <Gordon.Sande(a)gmail.com> wrote:
>
>> There are various "definitions" of undefined. Many are so watered down
>> that it takes a skilled lawyer to show why they are not fraudulent. If
>> you don't notice the distinctions you can be fooled into treating them as
>> all the same.
>>
>> The useful definition is that the variable has never been assigned a value
>> by the user after the variable has come into existence.
>
> There is also the definition in the Fortran standard. That one probably
> falls into the category of taking a skilled lawyer, but it is one that
> is particularly relevant to Fortran. Note that it is not particularly
> close to the same definition as the one you refer to above as "the
> useful definition." For example, the f2003 standard lists 18 ways for a
> variable to become undefined, and some of those 18 ways include multiple
> subitems, so that the list might plausibly said to have about 30 ways.

Thanks for the long answer. When one tries for a short posting one often
falls short. After posting I though that I should have said that one would
just use the definition of the Fortran standard. I was trying to be useful
without being long winded but clearly fell short.

> Yes, it takes a language lawyer to read some of them, but others are
> pretty important and useful to know. People get bit by several of them,
> sometimes even when the people do know the rules and violate them by
> accident. That's happened to me. I'm thinking of a case where I
> accidentally declared a dummy argument to be intent(out), which made the
> actual argument become undefined, even if it had been previously
> defined. That code worked for several years until a new version of the
> compiler behaved differently from the version I had been using.

I do my own storage management in a sparse array code and wanted to use the
undefined variable checking that NAG has as a help. Someone in the newsgroup
pointed out that I could use exactly that trick to get NAG to mark storage
that I had released as undefined as well. It did not find any errors
so I guess I had been carefull. Belt and suspenders are helpful.


From: Gordon Sande on
On 2010-05-26 15:55:49 -0300, JB <foo(a)bar.invalid> said:

> On 2010-05-26, Gordon Sande <Gordon.Sande(a)gmail.com> wrote:
>> On 2010-05-26 11:50:56 -0300, JB <foo(a)bar.invalid> said:
>>
>>> On 2010-05-26, Gordon Sande <Gordon.Sande(a)gmail.com> wrote:
>>>> The useful definition is that the variable has never been assigned a value
>>>> by the user after the variable has come into existence. The descriptions
>>>> of Valgrind I have seen to not include such a capability.
>>>
>>> Would you say that the following example constitutes detection of an
>>> uninitialized variable, or what is it?
>>>
>>> program vt
>>> integer :: ii
>>> print *, ii
>>> end program vt
>>>
>>> $ valgrind --track-origins=yes ./a.out
>>> ==27324== Memcheck, a memory error detector
>>> ==27324== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al.
>>> ==27324== Using Valgrind-3.5.0 and LibVEX; rerun with -h for copyright info
>>> ==27324== Command: ./a.out
>>> ==27324==
>>> ==27324== Conditional jump or move depends on uninitialised value(s)
>>> ==27324== at 0x4C526F5: ??? (in /usr/lib64/libgfortran.so.3.0.0)
>>> ==27324== by 0x4CFD144: ??? (in /usr/lib64/libgfortran.so.3.0.0)
>>> ==27324== by 0x4D006DE: ??? (in /usr/lib64/libgfortran.so.3.0.0)
>>> ==27324== by 0x40076B: MAIN__ (vt.f90:3)
>>> ==27324== by 0x4007A9: main (in /home/job/src/valgrindtest/a.out)
>>> ==27324== Uninitialised value was created by a stack allocation
>>> ==27324== at 0x400711: MAIN__ (vt.f90:1)
>>> ...
>>>
>>> valgrind is not that good at detecting stack allocations; as you can
>>> see, it only gives the line where the procedure starts, not which
>>> variable is guilty. Heap detection is generally better, and usually at
>>> least, gives directly the line where the error occurs and where the
>>> variable was declared. (The ???'s are because for some reason
>>> libgfortran was not compiled with debug symbols included)
>>>
>>> And, as I mentioned in my previous message, if the ii variable is made
>>> SAVE, then valgrind won't detect it, as the compiler sets it to 0, and
>>> valgrind in it's somewhat C-centric worldview thinks everything is ok.
>>
>> A rather watered down defintion of detecting an undefined variable.
>
> How come? You yourself provided a defition for detecting undefined
> variables as "The useful definition is that the variable has never
> been assigned a value by the user after the variable has come into
> existence". Then you claimed that valgrind cannot detect such errors
> "The descriptions of Valgrind I have seen to not include such a
> capability.". And then I provided a trivial counterexample where
> valgrind was indeed able to detect such a use of an undefined
> variable.
>
> Seems like you're trying to sucker me into a game of moving the
> goalposts.

Good debating technique! I used a short definition rather than a long one
which should have been "as in the Fortran standard". My failure. Your example
requires so many side conditions that it fails to be useful for other
than simple cases.

Lahey, NAG and Silverfrost exist for current Fortran and find undefined
variables without an extensive list of side conditions.

Static analysis from a compiler with flow analysis will find many simple
cases. The real examples that folks seem to be posing are using undefined
variables that other than the simplest case as they are array elements or
in common.

>> Simple
>> flow analysis yields this as an uninitialized variable for many compilers.
>
> Yes. What does that have to do with valgrind?
>
>> Are you sure you didn't take at least first year law school
>
> No, I didn't. I once had a girlfriend who was studying law, though, in
> case you feel that's somehow pertinent to the argument.
>
>> if that is
>> your example of useful undefined variable checking? ;-)
>
> Well, the example wasn't intented to show the limits of what valgrind
> is capable of, just that contrary to previous claims, it can indeed
> detect use of uninitialized variables.
>
> I have successfully used valgrind to find uses of uninitialized
> variables, and other common memory errors that I myself, and others,
> have made, so yes, I find it useful, despite it perhaps never
> fulfilling some yet to be heard criteria for perfection.

Any mechanical aids is better than none. When there are various levels of aids
available it is not helpful to claim the ones for simple problems can solve
the hard problems. Lots of problem are simple but there are problems that
are not. If a problem keeps coming back the assumption that it is simple
becomes less and less tenable.

You seem to suggest that the checking done by Lahey, NAG and Silverfrost
is some impossible level of perfection. To quote an old advetising slogun
"Ask a man who owns one" or simply try one as Silverfrost is free for
personal use.

>> Try something like setting the 1st and 3rd element of an array and referecing
>> the 2nd element. And make these subscript values data values so there
>> can be no static analysis. The systems I gave (but you snipped) all will find
>> that the 2nd element is undefined.
>
> I sort of fear that a testcase I do myself will, like my previous one,
> not be up to your high standards, so why don't you provide the code
> that I can test since you already seem to have it?
>
>>> Ok. IMHO, instrumentation and sampling based profiling are useful for
>>> different, although to some extent overlapping, purposes, and both
>>> are, well, again IMHO, clearly profiling.
>>
>> And one is rather thin gruel if you are expecting the real thing.
>
> Yes, I tried to imply that with my comment that they are useful for
> different purposes (assuming here that the "real thing" refers to the
> profiling approach more appropriate for the task at hand).


From: Gordon Sande on
On 2010-05-26 16:40:02 -0300, steve <kargls(a)comcast.net> said:

> On May 26, 11:55�am, JB <f...(a)bar.invalid> wrote:
>> On 2010-05-26, Gordon Sande <Gordon.Sa...(a)gmail.com> wrote:
>>
>>
>>
>>> On 2010-05-26 11:50:56 -0300, JB <f...(a)bar.invalid> said:
>>
>>>> On 2010-05-26, Gordon Sande <Gordon.Sa...(a)gmail.com> wrote:
>>>>> The useful definition is that the variable has never been assigned a
> value
>>>>> by the user after the variable has come into existence. The descripti
> ons
>>>>> of Valgrind I have seen to not include such a capability.
>>
>>>> Would you say that the following example constitutes detection of an
>>>> uninitialized variable, or what is it?
>>
>>>> program vt
>>>> � integer :: ii
>>>> � print *, ii
>>>> end program vt
>>
>>>> $ valgrind --track-origins=yes ./a.out
>>>> ==27324== Memcheck, a memory error detector
>>>> ==27324== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Se
> ward et al.
>>>> ==27324== Using Valgrind-3.5.0 and LibVEX; rerun with -h for c
> opyright info
>>>> ==27324== Command: ./a.out
>>>> ==27324=
>>>> ==27324== Conditional jump or move depends on uninitialised va
> lue(s)
>>>> ==27324== � �at 0x4C526F5: ??? (in /usr/lib64/libgfortran.
> so.3.0.0)
>>>> ==27324== � �by 0x4CFD144: ??? (in /usr/lib64/libgfortran.
> so.3.0.0)
>>>> ==27324== � �by 0x4D006DE: ??? (in /usr/lib64/libgfortran.
> so.3.0.0)
>>>> ==27324== � �by 0x40076B: MAIN__ (vt.f90:3)
>>>> ==27324== � �by 0x4007A9: main (in /home/job/src/valgrindt
> est/a.out)
>>>> ==27324== �Uninitialised value was created by a stack alloca
> tion
>>>> ==27324== � �at 0x400711: MAIN__ (vt.f90:1)
>>>> ...
>>
>>>> valgrind is not that good at detecting stack allocations; as you can
>>>> see, it only gives the line where the procedure starts, not which
>>>> variable is guilty. Heap detection is generally better, and usually at
>>>> least, gives directly the line where the error occurs and where the
>>>> variable was declared. (The ???'s are because for some reason
>>>> libgfortran was not compiled with debug symbols included)
>>
>>>> And, as I mentioned in my previous message, if the ii variable is made
>>>> SAVE, then valgrind won't detect it, as the compiler sets it to 0, and
>>>> valgrind in it's somewhat C-centric worldview thinks everything is ok.
>>
>>> A rather watered down defintion of detecting an undefined variable.
>>
>> How come? You yourself provided a defition for detecting undefined
>> variables as "The useful definition is that the variable has never
>> been assigned a value by the user after the variable has come into
>> existence". Then you claimed that valgrind cannot detect such errors
>> "The descriptions of Valgrind I have seen to not include such a
>> capability.". And then I provided a trivial counterexample where
>> valgrind was indeed able to detect such a use of an undefined
>> variable.
>>
>> Seems like you're trying to sucker me into a game of moving the
>> goalposts.
>>
>>> Simple
>>> flow analysis yields this as an uninitialized variable for many compile
> rs.
>>
>> Yes. What does that have to do with valgrind?
>>
>>> Are you sure you didn't take at least first year law school
>>
>> No, I didn't. I once had a girlfriend who was studying law, though, in
>> case you feel that's somehow pertinent to the argument.
>>
>>> if that is
>>> your example of useful undefined variable checking? ;-)
>>
>> Well, the example wasn't intented to show the limits of what valgrind
>> is capable of, just that contrary to previous claims, it can indeed
>> detect use of uninitialized variables.
>>
>> I have successfully used valgrind to find uses of uninitialized
>> variables, and other common memory errors that I myself, and others,
>> have made, so yes, I find it useful, despite it perhaps never
>> fulfilling some yet to be heard criteria for perfection.
>>
>>> Try something like setting the 1st and 3rd element of an array and refe
> recing
>>> the 2nd element. And make these subscript values data values so there
>>> can be no static analysis. The systems I gave (but you snipped) all wil
> l find
>>> that the 2nd element is undefined.
>>
>> I sort of fear that a testcase I do myself will, like my previous one,
>> not be up to your high standards, so why don't you provide the code
>> that I can test since you already seem to have it?
>>
>
> laptop:kargl[215] gfc4x -o z k.f90
> laptop:kargl[216] valgrind ./z
> ==23180== Memcheck, a memory error detector
> ==23180== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward
> et
> al.
> ==23180== Using Valgrind-3.5.0 and LibVEX; rerun with -h for copyri
> ght
> info
> ==23180== Command: ./z
> ==23180=
> 2
> ==23180=
> ==23180== HEAP SUMMARY:
> ==23180== in use at exit: 0 bytes in 0 blocks
> ==23180== total heap usage: 0 allocs, 0 frees, 0 bytes allocated
> ==23180=
> ==23180== All heap blocks were freed -- no leaks are possible
> ==23180=
> ==23180== For counts of detected and suppressed errors, rerun with:
> -v
> ==23180== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 fr
> om
> 0)
> laptop:kargl[217] cat k.f90
> program gordon
> integer i(3)
> i(1) = 1
> i(2) = 2
> i(3) = 3
> print *, i(2)
> end program gordon
>
> After editing k.f90 to remove the i(2) assignment:
>
> k.f90: 7 lines, 92 characters.
> laptop:kargl[219] cat k.f90
> program gordon
> integer i(3)
> i(1) = 1
> i(3) = 3
> print *, i(2)
> end program gordon
>
> laptop:kargl[220] gfc4x -o z k.f90
> laptop:kargl[221] valgrind ./z
> ==23190== Memcheck, a memory error detector
> ==23190== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward
> et
> al.
> ==23190== Using Valgrind-3.5.0 and LibVEX; rerun with -h for copyri
> ght
> info
> ==23190== Command: ./z
> ==23190=
> ==23190== Conditional jump or move depends on uninitialised value(s
> )
> ==23190== at 0x8050ED4: gfc_itoa (write.c:917)
> ==23190== by 0x8050FB6: write_integer (write.c:1103)
> ==23190== by 0x805377C: _gfortrani_list_formatted_write (write.c
> :
> 1350)
> ==23190== by 0x80497C7: _gfortran_transfer_integer (transfer.c:
> 1779)
> ==23190== by 0x8048254: MAIN__ (in /usr/home/kargl/tmp/z)
> ==23190== by 0x80482A5: main (in /usr/home/kargl/tmp/z)
>
> There are 6 such blocks spewed by valgrind followed by
>
>
> ==23190=
> ==23190== Syscall param write(buf) points to uninitialised byte(s)
> ==23190== at 0x80862BF: __sys_write (in /usr/home/kargl/tmp/z)
> ==23190== by 0x8053A27: _gfortrani_fbuf_flush (unix.h:54)
> ==23190== by 0x804A524: _gfortrani_next_record (transfer.c:3224)
> ==23190== by 0x804AC0B: finalize_transfer (transfer.c:3319)
> ==23190== by 0x804AD68: _gfortran_st_write_done (transfer.c:3427
> )
> ==23190== by 0x8048266: MAIN__ (in /usr/home/kargl/tmp/z)
> ==23190== by 0x80482A5: main (in /usr/home/kargl/tmp/z)
> ==23190== Address 0x40e402 is not stack'd, malloc'd or (recently)
> free'd
>
> Need to move the goal post a little further left.
>
> :-)

Very good. It would have been nice it one could figure that out by looking at
the documentaion for 10 minutes. Determining which variable was referenced
in which line seems a bit obscure to me. Where does it give that? I am lead
to believe that various standad Fortran forms will mask this problem as this
success is dependent on C semantics rather than Fortran semantics. Even the
simple single scalar example failed with the addition of SAVE according to
the other proponent of Valgrind. Such artifacts lower the utility of this
for debugging Fortran.

I must admit that I prefer the way NagFor reports the error with line number,
variable identifer and subscript all given compactly.

program Undef
implicit none
!
real :: a(3)
!
a(1) = 1.0
a(3) = 3.0
!
if ( a(2) > 0.0 ) then
write ( 6, '(1x,"a(2) positive")' )
else
write ( 6, '(1x,"a(2) nonpositive")' )
end if
!
stop
end

Gordons-Mac-9:NAG gordon$ nagfor -C=undefined Undef.f90
NAG Fortran Compiler Release 5.2(717)
[NAG Fortran Compiler normal termination]
Gordons-Mac-9:NAG gordon$ ./a.out
Runtime Error: Undef.f90, line 9: Reference to undefined variable A(2)
Program terminated by fatal error
Abort trap

The more subtle version is also reported out.

program Undef2
implicit none
!
real :: a(3)
!
a(1) = 1.0
a(2) = 2.0
a(3) = 3.0
call sam ( a )
!
if ( a(2) > 0.0 ) then
write ( 6, '(1x,"a(2) positive")' )
else
write ( 6, '(1x,"a(2) nonpositive")' )
end if
!
stop
!
contains
!
subroutine sam ( b )
!
implicit none
!
real, intent ( out ) :: b(:)
!
b(1) = 1.0
b(3) = 3.0
!
return
!
end subroutine
!
end

Gordons-Mac-9:NAG gordon$ nagfor -C=undefined Undef2.f90
NAG Fortran Compiler Release 5.2(717)
[NAG Fortran Compiler normal termination]
Gordons-Mac-9:NAG gordon$ ./a.out
Runtime Error: Undef2.f90, line 11: Reference to undefined variable A(2)
Program terminated by fatal error
Abort trap

When one tries a simpler version with scalars NagFor catchs the problem
at compile time. So one has to add a bit of trickery. The simpler form
is of interest as it is a case where a program will deliver different
(invalid in any case as the program is wrong) results for a copy-in/
copy-out style semantics compared to a call-by-reference style semantics.
Usually one requires aliasing to demonstrate such problems.

program Undef3
implicit none
!
real :: a
!
a = 3.0
call sam ( a )
!
if ( a > 0.0 ) then
write ( 6, '(1x,"a positive")' )
else
write ( 6, '(1x,"a nonpositive")' )
end if
!
stop
!
contains
!
subroutine sam ( b )
!
implicit none
!
real, intent ( out ) :: b
!
if ( .false. ) then
b = 1.0
end if
!
return
!
end subroutine
!
end

Gordons-Mac-9:NAG gordon$ nagfor -C=undefined Undef3.f90
NAG Fortran Compiler Release 5.2(717)
[NAG Fortran Compiler normal termination]
Gordons-Mac-9:NAG gordon$ ./a.out
Runtime Error: Undef3.f90, line 9: Reference to undefined variable A
Program terminated by fatal error
Abort trap