public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug libstdc++/54351] New: ~unique_ptr() should not set __p to null
@ 2012-08-22 18:30 gromer at google dot com
  2012-08-22 18:44 ` [Bug libstdc++/54351] " redi at gcc dot gnu.org
                   ` (13 more replies)
  0 siblings, 14 replies; 15+ messages in thread
From: gromer at google dot com @ 2012-08-22 18:30 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54351

             Bug #: 54351
           Summary: ~unique_ptr() should not set __p to null
    Classification: Unclassified
           Product: gcc
           Version: 4.7.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: libstdc++
        AssignedTo: unassigned@gcc.gnu.org
        ReportedBy: gromer@google.com


libstdc++'s unique_ptr destructor is currently implemented as:

~unique_ptr() noexcept { reset(); }

This has the effect of resetting the stored pointer to null, and then invoking
the deleter on the formerly-stored pointer. I believe this is inconsistent with
the language standard, which specifies the destructor as "If get() == nullptr
there are no effects. Otherwise get_deleter()(get())." (note no mention of any
side effects on the value of the stored pointer). This is a problem because
this implementation will break code that (legitimately, AFAICT) relies on being
able to continue to invoke operations on the scoped_ptr while the destructor is
executing.

The fix is to reimplement the destructor (in both the base template and the
array specialization) as

~unique_ptr() noexcept {
 if (__p != pointer())
   get_deleter()(__p);
}

If the intent is to zero out __p to help catch use-after-destruction errors, I
believe it would be permissible to set __p to null after the call to
get_deleter(), because at that point the change would no longer be visible to
conforming code.

To make this concrete, here's an example: the following program prints "bad"
under libstdc++, but I believe a standard-conforming implementation is required
to print "good":

=============================
#include <iostream>
#include <memory>

using std::cout;
using std::endl;
using std::unique_ptr;

struct A;

struct B {
 unique_ptr<A> a;
};

struct A {
 B* b;
 ~A() {
   if (b->a == nullptr) {
     cout << "bad" << endl;
   } else {
     cout << "good" << endl;
   }
 }
};

int main(int argc, char** argv) {
 B b;
 b.a.reset(new A);
 b.a->b = &b;
}
===============================

As a point of comparison, MSVC++ 2010 prints "good" on this example program.


^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2015-05-27  9:11 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-08-22 18:30 [Bug libstdc++/54351] New: ~unique_ptr() should not set __p to null gromer at google dot com
2012-08-22 18:44 ` [Bug libstdc++/54351] " redi at gcc dot gnu.org
2012-08-22 18:47 ` redi at gcc dot gnu.org
2012-08-22 18:51 ` redi at gcc dot gnu.org
2012-08-22 18:58 ` redi at gcc dot gnu.org
2012-08-22 19:11 ` gromer at google dot com
2012-08-22 19:28 ` redi at gcc dot gnu.org
2012-08-22 19:49 ` [Bug libstdc++/54351] ~unique_ptr() should not set stored pointer " gromer at google dot com
2012-08-26  0:13 ` redi at gcc dot gnu.org
2012-08-26  0:30 ` redi at gcc dot gnu.org
2012-08-26  0:31 ` redi at gcc dot gnu.org
2012-12-18 21:59 ` gromer at google dot com
2015-05-26 23:45 ` rs2740 at gmail dot com
2015-05-27  8:01 ` redi at gcc dot gnu.org
2015-05-27  9:11 ` rs2740 at gmail dot com

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).