🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.std.c++
Article #3906

Re: Referencing pointers after delete

#3906
From: Martin D Kealey
Date: Wed, 03 Apr 1996 17:20
86 lines
4720 bytes
It seems that I didn't quite make myself clear; therefore I've
copied this to std-c++ in case anyone else is similarly confused.

I wrote:

> > Consider this implementation ... where every object contains ...
> > task pointer

> > Now, if we run out of normal registers and it is necessary to
> > spill the "current task" register, its value can be reloaded
> > through any register pointing at an object (say because register-
> > indirect might be faster than absolute addressing). The compiler
> > writer knows this will only be done if a valid pointer value is
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> > already in a register (and calling delete will invalidate the
> > register), since it would be more economical to obtain the value
> > some other way if a pointer to it isn't available).

Tom Payne <thp@cs.UCR.edu> wrote:

> If that pointer is chosen statically, one can correctly anticipate
> which pointer it will be and concoct a valid program that deletes the
> pointer's referent prior to the restoration of current-task:
>
>         Widget* p = anticipated();    // Referent gets deleted
>         delete p;                     // via the alias p.
>         // Code to cause current-task to be spilled and restored.
                                                      ^^^^^^^^^^^^

This misses a critical point -- "Code to cause current-task to be
spilled and restored" must explicitly refer to "p" as a non-lvalue
for the value of p to be involved in the reload; see later for the
explanation.

> If, for instance, delete zeros out the deleted object, this valid
> program will crash and burn.  It seems to require run-time checking
> (and overhead) to avoid this.

Only if the risk of aliasing is undetectable at compile time; in
fact even a conservative approach can guarantee non-aliasing in
some cases -- but see later.

> The crashing and burning discussed above is not a result of the
> program reading an invalid pointer but of the implementation
> dereferencing one and using data from its deleted referent.

In a word, no.

I said explicitly that if the pointer was deleted then the
register would be invalidated so that it would NOT be used.

If the program never mentions p again, it won't crash (*) because
the value in the register has been invalidated; if it does use the
value of p, then it doesn't meet the standard's current
requirement.

(*  At least, it won't crash because of this potential problem; I
    can't speak for whatever other bugs the program might have.)

> How do you know that value is "valid"?  Perhaps, we've invalidated it
> by deleting its referent through another pointer to the same object?

*Sigh*  This is not supposed to be a complete description, just an
example.  So ok, change it to invalidate all registers which
contain pointers to the same type as p, not just the single
register which contains the value of p.  Also, *all* registers are
invalidated over (non-inline) function calls, or any other time
we're not 100% sure what they might contain.

I think now that accidental use of register aliasing is not
possible -- one has explicitly to use p (or an alias for it) as a
non-lvalue in the source code to cause this effect, and that means
the program is non-conforming.

I know this is a perverse implementation that does some pretty
fantastic peephole optimising without bothering to do any dataflow
analysis, but that alone doesn't currently make it non-conforming.

- Martin.
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your 
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu 
]
Technical Details
Message-ID: <m0u4G70-000GcEC@7.kurahaupo.gen.nz>
Path: arc1-ca.pugleaf.net!fido.asd.sgi.com!austern

Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!fido.asd.sgi.com!austern
From: martin@kcbbs.gen.nz (Martin D Kealey)
Newsgroups: comp.std.c++
Subject: Re: Referencing pointers after delete
Date: 03 Apr 1996 09:20:32 PST
Organization: -
Approved: austern@isolde.mti.sgi.com
Message-ID: <m0u4G70-000GcEC@7.kurahaupo.gen.nz>
NNTP-Posting-Host: isolde.mti.sgi.com
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 8bit
X-Original-Date: Wed, 3 Apr 1996 12:07:45 +1200 (NZST)
In-Reply-To: <199604010435.UAA16550@corvette.ucr.edu> from "Tom Payne" at Mar 31, 96 08:35:28 pm
X-Mailer: ELM [version 2.4 PL24]
X-Auth: PGPMoose V1.1 PGP comp.std.c++
 iQBVAwUBMWKzYUy4NqrwXLNJAQFXqwH/eYjKJH0y7mb0J79PTFpuN3rpT/LXPafB
 cVJuUGB+JC1XWKse4lP5YzuSc94jWzuWAtW1cE9QEwYT7hYvlwMY5A==
 =++Oq
Originator: austern@isolde.mti.sgi.com