Bug 43820 - [4.4/4.5/4.6 Regression] auto_ptr used with incomplete type no longer triggers warning
Summary: [4.4/4.5/4.6 Regression] auto_ptr used with incomplete type no longer trigger...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: libstdc++ (show other bugs)
Version: 4.4.3
: P2 normal
Target Milestone: 5.0
Assignee: Jonathan Wakely
URL:
Keywords: diagnostic
Depends on:
Blocks:
 
Reported: 2010-04-20 16:11 UTC by Romain Lerallut
Modified: 2017-04-20 12:07 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work: 4.1.2
Known to fail: 4.4.3, 4.5.0
Last reconfirmed: 2010-04-21 09:36:11


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Romain Lerallut 2010-04-20 16:11:17 UTC
The following code used to trigger a warning with gcc 4.2 and 4.3 but passes silently with 4.4 and 4.5:

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

struct S;

int main()
{
   std::auto_ptr<S> p( (S*) 1234 );
}
=====================================

This code triggers a segfault but when the pointer is actually from a real object, then its destructor simply is not called and resources are leaked.
Comment 1 Jonathan Wakely 2010-04-20 16:21:38 UTC
Could be a front-end bug, but probably something in the library
Comment 2 Chris Jefferson 2010-04-20 17:10:23 UTC
I think this is connected to the "suppress warning is the standard library" pragma starting to actually work.
Comment 3 Paolo Carlini 2010-04-20 17:17:52 UTC
And frankly note that anything related to auto_ptr is very unlikely to change, given the deprecation status, unless it's something like the code doesn't compile anymore.
Comment 4 Chris Jefferson 2010-04-20 17:18:56 UTC
Yes, in C++0x mode, we should just add a deprication warning for auto_ptr full stop.
Comment 5 Jonathan Wakely 2010-04-20 18:22:46 UTC
sure, it's deprecated in C++0x mode, but it's a pretty bad regression that it no longer warns in C++03 mode

Chris is right, -Wsystem-headers restores the warning
Comment 6 Paolo Carlini 2010-04-20 18:30:52 UTC
To me it looks like a front-end issue.
Comment 7 Paolo Carlini 2010-04-20 18:36:28 UTC
Maybe I should clarify my earlier message: at this time in the life of auto_ptr, it seems quite unlikely to me that we'll non-trivially change the implementation only because a warning is not emitted anymore. If either the change is trivial, or the issue is really a front-end issue (not limited to auto_ptr, likely), then it would be fine of course.
Comment 8 Romain Lerallut 2010-04-20 18:41:33 UTC
@Chris Jefferson : indeed, if I roll my own "auto_ptr" locally, I get the proper warning, as well as if I use -Wsystem-headers (didn't know that one). 

@Paolo Carlini : I'm using the default standard mode for gcc 4.4, so I guess that's C++03 in which std::auto_ptr is *not* deprecated.


By the way, there's no warning with -Wall or even -Wextra. Is there a flag -Wabsolutely_all_warnings_we_promise  that I have missed and that would really enable *all* warnings ?

Comment 9 Chris Jefferson 2010-04-20 18:53:52 UTC
I don't think it's a front-end issue. '#pragma GCC system_header' is specifically designed to stop warnings in headers. However, it stops 'good' warnings as well as 'bad' warnings. 'system_header' could be extended to allow (or disallow) specific warnings, but that seems like quite a major extension.

Romain: -Wsystem-headers will enable warnings in standard library types. However note that you will get some warnings thrown up, which you won't be able to work around.

The only real patch I can think of would be to avoid '#pragma GCC system_header' being defined in C++03 mode, in <memory>. That would be a simple patch like the below. The only problem is that this might left some other warnings sneak back in. Something like (untested, sorry).


Index: memory
===================================================================
--- memory	(revision 158569)
+++ memory	(working copy)
@@ -44,7 +44,9 @@
 #ifndef _GLIBCXX_MEMORY
 #define _GLIBCXX_MEMORY 1
 
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
 #pragma GCC system_header
+#endif
 
 /**
  * @defgroup memory Memory
Comment 10 Paolo Carlini 2010-04-20 18:59:23 UTC
Nah, the pragma must stay, we have it everywhere, consistently. And I really do not understand why auto_ptr is *so* special to need more warnings to be spilled vs *all* the rest of the library in order to be used safely. Ah, yes, it's broken, forgot ;) Really, if this is the ultimate analysis of the issue, I disagree with doing *anything*.
Comment 11 Romain Lerallut 2010-04-20 19:09:53 UTC
I don't think auto_ptr is special and I, as a mere user, would appreciate you didn't hide *helpful* warnings from anywhere (but I do also appreciate your efforts in limiting spurious warnings !).

I have the option of using boost's scoped_ptr (which wouldn't have compiled in the first place, even better) so I won't argue the issue any longer.

Thank you all for your time.
Comment 12 Jonathan Wakely 2010-04-21 09:23:18 UTC
(In reply to comment #8)
> By the way, there's no warning with -Wall or even -Wextra. Is there a flag
> -Wabsolutely_all_warnings_we_promise  that I have missed and that would really
> enable *all* warnings ?

No, sorry, there isn't. 

(In reply to comment #10)
> Nah, the pragma must stay, we have it everywhere, consistently. And I really do
> not understand why auto_ptr is *so* special to need more warnings to be spilled
> vs *all* the rest of the library in order to be used safely. Ah, yes, it's
> broken, forgot ;) Really, if this is the ultimate analysis of the issue, I
> disagree with doing *anything*.

:)
the reason isn't that it's broken, it's that various members of auto_ptr require the expression "delete _M_ptr" to be well-formed, and warning users when it's not well-formed is very useful.  Previously we never added a check because the front-end warned.

even if you don't care about auto_ptr (and I still do) THIS AFFECTS SHARED_PTR TOO!

We no longer warn on this:

struct C;
C* f();
std::shared_ptr<C> p( f() );


Chris's patch definitely won't work, since it would affect the rest of <memory> not just auto_ptr.  Something like "#pragma pop GCC system_header" would work, and would also make the attribute((deprecated)) on auto_ptr work again!

For the std::shared_ptr case I will add a static_assert like we use in unique_ptr.  tr1::shared_ptr will have to use an array of sizeof(T) length or something

Comment 13 Paolo Carlini 2010-04-21 17:04:12 UTC
static_asserts are fine, of course. Otherwise, if the real issue is that errors coming from system headers are suppressed and shouldn't, sometimes, from the user point of view, that is a **front-end** issue, about the semantics of the pragma. Actually, I'm sure it has been discussed already, somewhere, Ian also participated (this PR could well be a duplicate), and the front-end people should be involved in the discussion.
Comment 14 Paolo Carlini 2010-04-21 17:11:12 UTC
Forgot: before doing anything about those diagnostic issues, we should double check what other compilers do with / without our library, thus, say current ICC / something else (even among those available online, Comeau, Dinkumware...)
Comment 15 Jonathan Wakely 2010-04-21 17:41:09 UTC
Comeau warns on the auto_ptr case.  boost::shared_ptr refuses to compile if the type is incomplete
Comment 16 Paolo Carlini 2010-04-21 18:18:09 UTC
Note I'm traveling, thus I have limited capabilities. I strongly recommend digging out that conversation about the pragma itself, with Ian too involved, and trying to put to good use static_asserts and any other template-based tricks, per boost.
Comment 17 Jonathan Wakely 2010-04-21 18:26:56 UTC
ok, thanks for the pointers, I'll hunt for the discussion
Comment 18 Paolo Carlini 2010-04-21 18:48:36 UTC
c++/43167 ?
Comment 19 Jonathan Wakely 2010-04-21 18:59:34 UTC
thanks!
Comment 20 Jonathan Wakely 2010-05-27 10:55:12 UTC
I have a patch which causes an error if std::shared_ptr or std::tr1::shared_ptr is constructed with a pointer to incomplete type and no custom deleter.  I'm not sure what the best approach is for auto_ptr. Technically it's invalid to instantiate auto_ptr with an incomplete type, but in practice only reset() and ~auto_ptr() need the complete type. I can make it an error to instantiate those members with an incomplete type, but that could break some invalid programs which previously compiled with a warning and ran (with undefined behaviour)
For now I'll make the shared_ptr changes...
Comment 21 paolo@gcc.gnu.org 2010-05-31 18:41:49 UTC
Subject: Bug 43820

Author: paolo
Date: Mon May 31 18:41:33 2010
New Revision: 160082

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=160082
Log:
2010-05-31  Jonathan Wakely  <jwakely.gcc@gmail.com>

	PR libstdc++/43820
	* include/bits/shared_ptr_base.h: Require complete type.
	* include/tr1/shared_ptr.h: Likewise.
	* testsuite/20_util/shared_ptr/cons/43820.cc: New.
	* testsuite/tr1/2_general_utilities/shared_ptr/cons/43820.cc: New.

Added:
    trunk/libstdc++-v3/testsuite/20_util/shared_ptr/cons/43820.cc
    trunk/libstdc++-v3/testsuite/tr1/2_general_utilities/shared_ptr/cons/43820.cc
Modified:
    trunk/libstdc++-v3/ChangeLog
    trunk/libstdc++-v3/include/bits/shared_ptr_base.h
    trunk/libstdc++-v3/include/tr1/shared_ptr.h

Comment 22 Paolo Carlini 2010-06-10 13:38:01 UTC
Jon, I would recommend closing this. We don't want to fiddle with auto_ptr anyway, and the small issue with shared_ptr is fixed for 4.6.0.
Comment 23 Jonathan Wakely 2010-06-10 13:54:14 UTC
we have regressed in terms of the warning, but no diagnostic is required and auto_ptr is deprecated in C++0x, so WONTFIX
Comment 24 Jonathan Wakely 2017-04-20 12:07:21 UTC
This started working again with 5.1.0

ap.cc: In function ‘int main()’:
ap.cc:7:9: warning: ‘template<class> class std::auto_ptr’ is deprecated [-Wdeprecated-declarations]
    std::auto_ptr<S> p( (S*) 1234 );
         ^
In file included from /home/jwakely/gcc/5.1.0/include/c++/5.1.0/memory:81:0,
                 from ap.cc:1:
/home/jwakely/gcc/5.1.0/include/c++/5.1.0/bits/unique_ptr.h:49:28: note: declared here
   template<typename> class auto_ptr;
                            ^