[comp.lang.ada] A Bug in VAX Ada

ASP@SEI.CMU.EDU (Spencer Peterson) (01/09/88)

This message is a response to the perceived bug found with VAX Ada using
an access type, UNCHECKED_DEALLOCATION and a constant and a variable of 
the access type. "Ceci est un exemple..."

The "exemple" procedure/program is ERRONEOUS.  I quote, with meaningful 
substitutions, from the Ada Reference Manual( Chapter 13.10.1, Para. 6).

"If A and B designate the same object, then accessing that object through 
B is erroneous if this access is performed (or attempted) after the call 
DISPOSE(A); the effect of each such access is not defined by the language."

The program behaves as correctly as it can, given that it is 'legal' for
a compiler to optimize use of storage by NOT allocating a fresh copy of 
the string contents, although it would be prefered that a second copy be
made and thus, no problem would occur when the original is DISPOSEd. The
effect of making a copy of the contents of an access type, in this case,
is the same as if B were a constant of type ACCESS_STRING, i.e.
   B : constant ACCESS_STRING := A;

Spencer Peterson
Member of The Technical Staff
Software Engineering Institute
Carnegie Mellon University
5000 Forbes Ave.
Pittsburgh, PA 15213
412-268-7608
 

paul@cernvax.UUCP (paul) (01/11/88)

Seems odd to me that it should be legal to optimise an otherwise good
program (in my opinion) into one that doesn't work any more.

Does anyone else think the program is erroneous?

Paul

firth@sei.cmu.edu (Robert Firth) (01/13/88)

In article <596@cernvax.UUCP> paul@cernvax.UUCP () writes:
>Seems odd to me that it should be legal to optimise an otherwise good
>program (in my opinion) into one that doesn't work any more.
>
>Does anyone else think the program is erroneous?
>
>Paul

Just to refresh your memory, here is the program:

========

    A bug in Vax Ada compiler ?
    ---------------------------
     
    just have a look at that short procedure:
    
    with UNCHECKED_DEALLOCATION;
    with TEXT_IO;
    procedure G_ADA_BUG is
      type ACCESS_STRING is access STRING;
      procedure DISPOSE is new UNCHECKED_DEALLOCATION (STRING, ACCESS_STRING);
      A: ACCESS_STRING := new STRING'("Ceci est un exemple...");
      B: constant STRING := A.all;
    begin -- G_ADA_BUG
     TEXT_IO.PUT_LINE (A.all);
     TEXT_IO.PUT_LINE (B);
     DISPOSE (A);
     TEXT_IO.PUT_LINE (B);
   end G_ADA_BUG;
    
      I have compiled (with default options) it with Vax Ada V1.4-33
    running under Vax/Vms V4.5 on a Vax-8600.  
    
      The expected result is:
    
    Ceci est un exemple...
    Ceci est un exemple...
    Ceci est un exemple...
    
      But I got it:
    
Ceci est un exemple...
Ceci est un exemple...
%SYSTEM-F-ACCVIO, access violation, reason mask=00, virtual address=7FF3EA00, PC=00013FF3, PSL=0BC00000
%TRACE-F-TRACEBACK, symbolic stack dump follows
...

========

In my opinion, the program is not erroneous and the compiler is buggy.

There is no aliasing in the source code.  The line

	B : constant STRING := A.all

specifically requests a copy of the string from the object designated
by A into the local constant object B.  For the compiler to share the
actual string is illegitimate.  (In general, it is not a correct program
transformation to alias two objects of different and overlapping extent)

ron@inmet.UUCP (01/14/88)

This program is definitely legal.  One of the holes in the analysis leading
to the incorrect "program is erroneous" conclusion is the assertion that B, a
string typed object, "designates" the string object.  In fact, "designates"
is a technical term applicable only to access types and tasks; the assignment
involved in B's elaboration simply sets the "value" of B.  Although the value
assigned happens to be the value designated by A, this is irrelevent after
the assignment.

Have you tried compiling it with the /nooptimize switch?  I bet that you'll
get more appropriate behavior. 

Over the last few years, I've encountered various bugs with the VAX Ada
compiler's handling of access types.  The simplest (and my personal
favorite) example is that Unchecked_Deallocation(null) raises
Program_Error.  This is my favorite because the only concrete thing
that the LRM has to say about Unchecked_Deallocation is that after any
call to Unchecked_Deallocation(x), x is null.

firth@sei.cmu.edu (Robert Firth) (01/18/88)

In article <124000008@inmet> ron@inmet.UUCP writes:

>Over the last few years, I've encountered various bugs with the VAX Ada
>compiler's handling of access types.  The simplest (and my personal
>favorite) example is that Unchecked_Deallocation(null) raises
>Program_Error.  This is my favorite because the only concrete thing
>that the LRM has to say about Unchecked_Deallocation is that after any
>call to Unchecked_Deallocation(x), x is null.

Sorry, not so.  RM 13.10.1 (b) says explicitly

	" FREE(X), when X is already equal to null, has no effect"

(where FREE is an instantiation of UNCHECKED_DEALLOCATION)

We discussed this point, and decided that it was appropriate for
FREE to take very weak preconditions.  Note also that Ada doesn't
require X to be the only variable whose value designates the
deallocated object, merely that you don't subsequently use such
a value to access the object.

We also decided to say most of this explicitly, to avoid the kind of
oversight that the above compiler seems to have made.  This might
seem needlessly pedantic (after all, who would do it any other way?),
but I'm glad we were mistrustful.

I can recall another important issue where we DID trust the
implementors.  The question was raised at one DR meeting: should
we say explicitly that one task doing input from a slow device
does not cause the whole program to block?  The response was almost
universal stupified disbelief that any implementor would ever be
so incompetent as to do it that way.  Sigh!