While working on a further simplification of the is_constructible traits using gcc 4.8.0 20120930 (experimental) with the compiler flags -Wall -pedantic -std=c++11 the following program demonstrates that private access of a *defaulted* destructor is not properly respected during delete expressions: //-------------------- #include <new> template<class T> T&& declval(); struct P1 { private: ~P1(); }; struct P2 { ~P2() = delete; }; struct P3 { private: ~P3() = default; }; typedef decltype(::delete declval<P1*>()) t1; // #20 typedef decltype(::delete declval<P2*>()) t2; // #21 typedef decltype(::delete declval<P3*>()) t3; // #22 *Not* detected //-------------------- This program produces only two errors instead of the expected three: "main.cpp|8|error: 'P1::~P1()' is private| main.cpp|20|error: within this context| main.cpp|21|error: use of deleted function 'P2::~P2()'| main.cpp|12|error: declared here| " According to [expr.delete] p10 access control shall be done for the destructor.
Uhm, this is not trivial to fix. The difference between P1 and P3 is that for the former from build_delete we call build_dtor_call which eventually also calls the required perform_or_defer_access_check, whereas for the latter the function just notices that TYPE_HAS_TRIVIAL_DESTRUCTOR and early returns (via build_op_delete_call). Arguably, a TYPE_HAS_TRIVIAL_DESTRUCTOR true for a destructor which actually is private and can't be called sounds a bit strange but for sure the choice makes sense wrt the rest of the front-end and the standard... I'll double check soon a few things. Anyway, here, I only wanted to ask you if this is a show-stopper for your work, because I don't know how much time it will take.
(In reply to comment #1) > Anyway, here, I only wanted to ask you if this is a show-stopper for your work, > because I don't know how much time it will take. While I think that this should be fixed, it will only prevent that I would directly convert is_constructible to use the combined ::delete ::new ((void*) nullptr) T(args) expression. Our current implementation is not sensitive to this problem, because we use is_destructible within. I noticed that there are still a bunches of opportunities to simplify is_constructible (and friends) because a lot of previous compiler defects have been fixed. So, really no need to hurry!
Of course it should be fixed, it *must* be fixed, actually! And it's really annoying that this bug affecting private defaulted destructors (which, I bet, aren't that common for most programs not using SFINAE tricks!?!) is preventing us from deploying right now the very elegant ::delete ::new pattern which otherwise finally works pretty well. What can I add? Do your best, and thanks again!
Let's ask Jason right now, if he can see a smart way to do access control on defaulted destructors...
By the way, this compiles: struct P3 { private: ~P3() = default; }; P3 p3; thus there is little hope that we get an error for #22 ..
(In reply to comment #5) I double-checked whether this might be related to http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1507 from a different perspective, but I'm pretty sure it isn't. 12.4 p11 seems very clear that the destructor would be called implicitly here and that access checking happens.
Various places in the compiler need to be updated to not assume that trivial implies callable.
*** Bug 57595 has been marked as a duplicate of this bug. ***
*** Bug 56429 has been marked as a duplicate of this bug. ***
(In reply to Paolo Carlini from comment #3) > Of course it should be fixed, it *must* be fixed, actually! And it's really > annoying that this bug affecting private defaulted destructors (which, I > bet, aren't that common for most programs not using SFINAE tricks!?!) The bug affects protected destructors too, and they're commonly used for base classes to prevent deletion via pointer-to-base. This bug means you can't make them trivial by defining them as defaulted. The problem isn't confined to delete expressions as the example from PR56429 shows: class A { A() = default; }; struct B : A { }; B b;
Jason call if we want this to be a P2. Well, maybe some wrong code bugs I recently bumped to P2 should be P1 ;)
Thus this is fixed in r203985.
Author: paolo Date: Fri Oct 25 10:54:56 2013 New Revision: 204057 URL: http://gcc.gnu.org/viewcvs?rev=204057&root=gcc&view=rev Log: 2013-10-25 Paolo Carlini <paolo.carlini@oracle.com> PR c++/54812 * g++.dg/cpp0x/defaulted47.C: New. Added: trunk/gcc/testsuite/g++.dg/cpp0x/defaulted47.C Modified: trunk/gcc/testsuite/ChangeLog
*** Bug 61087 has been marked as a duplicate of this bug. ***
Timely post ! For my two cents , if others wants to merge PDF or PNG files , my friend came across a tool here <a href="http://www.altomerge.com/" >http://www.AltoMerge.com</a>.