------- Additional Comments From SWElef at post dot sk 2004-12-20 17:09 ------- (In reply to comment #13) > Here's a condensed version of Wolfgang's testcase: > ==================================== > int i=1; > class A; > template<int> struct B > { > A *p; > ~B() > { > --i; > p=0; > if(p) delete p; > } > }; > class C : B<0> {}; > class A { C c; }; > int main() > { > { C c; } > return i; > }
This is not a "condensed version of Wolfgang's testcase". While Wolfgang's testcase is well-formed, your is ill-formed. The difference is that it uses a pointer to object of _non-dependent_ incomplete type, i.e. it is invalid according to tc1:14.6/7: Knowing which names are type names allows the syntax of every template definition to be checked. No diagnostic shall be issued for a template definition for which a valid specialization can be generated. If no valid specialization can be generated for a template definition, and that template is not instantiated, the template definition is ill-formed, no diagnostic required. If a type used in a non-dependent name is incomplete at a point at which a template is defined but is complete at the point at which an instantiation is done, and if the completeness of that type affects whether or not the program is well-formed or affects the semantics of the program, the program is ill-formed; no diagnostic required. [Note: ...] The details are very subtle because the template definition is not ill-formed by itself. std:5.3.5/5 says If the object being deleted has incomplete class type at the point of deletion and the complete class has a non-trivial destructor or a deallocation function, the behavior is undefined. Thus, it would be well defined if the class A was later completed with trivial destructor and no class specific deallocation function. It is ill-formed because class A was incomplete at the point of definition of B<int>::~B(), it was later defined with non-trivial destructor _and_ B<0>::~B() (with "delete p;") was instantiated. For example the snippet from comment #14 _as short as it is_ is AFAICT well-formed. In this context it might be important to note that starting from gcc3.4 we have the two phase lookup. gcc3.4+ should be able to issue the same warning for the expression "delete p;" as for an ordinary delete expression involving an incomplete type. Regards, Vladimir Marko -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=17648