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

Reply via email to