------- 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