/* PR c++/98305 spurious -Wmismatched-new-delete on template instance { dg-do compile } { dg-options "-Wall" } */ typedef __SIZE_TYPE__ size_t; void sink (void*, ...); template struct A1 { A1 (); void* operator new (size_t); void operator delete (void*); void* operator new[] (size_t); void operator delete[] (void*); template struct A2 { A2 (); void* operator new (size_t); void operator delete (void*); void* operator new[] (size_t); void operator delete[] (void*); }; }; void test_a1 () { { A1 *p = new A1(); sink (p); delete p; } { A1 *p = new A1(); sink (p); delete p; } { void *p = new A1(); A1 *q = (A1*)p; sink (q); delete q; // { dg-warning "-Wmismatched-new-delete" } } } void test_a2 () { { A1::A2 *p = new A1::A2(); sink (p); delete p; } { A1::A2 *p = new A1::A2(); sink (p); delete p; } { A1::A2 *p = new A1::A2(); sink (p); delete p; } typedef A1::A2 A; { A *p = (A*)new A1::A2(); sink (p); delete p; // { dg-warning "-Wmismatched-new-delete" } } { A *p = (A*)new A1::A2(); sink (p); delete p; // { dg-warning "-Wmismatched-new-delete" } } { A *p = (A*)new A1::A2(); sink (p); delete p; // { dg-warning "-Wmismatched-new-delete" } } } template struct B1 { B1 (); void* operator new (size_t); void operator delete (void*); void* operator new[] (size_t); void operator delete[] (void*); template struct B2 { B2 (); void* operator new (size_t); void operator delete (void*); void* operator new[] (size_t); void operator delete[] (void*); }; }; void test_b_b () { typedef B1 B1c; typedef B1c::B2 B1cB2B1c; { B1cB2B1c *p = new B1cB2B1c; sink (p); delete p; } { B1cB2B1c *p = new B1cB2B1c[1]; sink (p); delete[] p; } } void test_a_b () { typedef B1::B2 B; { B *p = (B*)new A1::A2[1]; sink (p); delete[] p; // { dg-warning "-Wmismatched-new-delete" } } { B *p = (B*)new A1::A2[2]; sink (p); delete[] p; // { dg-warning "-Wmismatched-new-delete" } } { B *p = (B*)new A1::A2[3]; sink (p); delete[] p; // { dg-warning "-Wmismatched-new-delete" } } }