------- Additional Comments From prw at ceiriog1 dot demon dot co dot uk 2005-04-30 07:37 ------- I may have a discovered a related bug with a large program using STL (hash_set). I've tried to simplify somewhat, and I have some comments arising from some hacking with gdb (ddd). As a previous poster on duplicate Bug #20584 observed, it seems to be related to #pragma interface. In this example the problem is with the ~hash_set destructor, which is never defined explicitly but needs to be synthesized to destroy the _M_ht member. This destructor is never instantiated anywhere.
This problem occurs with the 4.0.0 distribution. Just do g++ bug-example.cc (if you can't reproduce the warning, I will post the preprocessed source also). FILE bug-example.h ------------------------------------------------------------ #pragma interface #include <ext/hash_set> using __gnu_cxx::hash_set; template <class Value, class HashFcn, class EqualKey> class SetData: public hash_set<Value *, HashFcn, EqualKey> { int i; public: SetData(void) {i = 1;} int foo() {} }; typedef int Loc; struct Loc_hash { size_t operator()(Loc *const &loc) const { return *loc; } }; struct Loc_eq { bool operator()(Loc *const &loc1, Loc *const &loc2) const { return (*loc1 == *loc2); } }; typedef SetData<Loc,Loc_hash,Loc_eq> LocSet; FILE bug-example.cc ---------------------------------------------------------- // If this is set we are OK. // #pragma implementation #include "bug-example.h" /* ================== Compile with -DEG1: We are OK Compile with -DEG2: We get a warning: bug-example.h:13: warning: inline function $-1ער__gnu_cxx::hash_set<Loc*, Loc_hash, Loc_eq, std::allocator<Loc*> >::~hash_set()עש used but never defined ~hash_set is not declared explicitly; but it is synthesized since one of the members (_M_ht) has a non-trivial destructor. Try setting the following breakpoint: (gdb) info b 1 Num Type Disp Enb Address What 1 breakpoint keep y 0x080d295f in lazily_declare_fn at ../../gcc/cp/method.c:1055 stop only if !({<text variable, no debug info>} 0x599b60 <strncmp>) (type->type.name->decl.name->identifier.id.str, "hash_set", 8) breakpoint already hit 2 times For EG1: Hit a breakpoint here: (gdb) c Breakpoint 1, lazily_declare_fn (sfk=sfk_destructor, type=0x41746bd0) at ../../gcc/cp/method.c:1055 (gdb) p type->type.name->decl.name->identifier.id.str $10 = (const unsigned char *) 0x8e6706a "hash_set<Loc*,Loc_hash,Loc_eq,std::allocator<Loc*> >" (gdb) p input_location $11 = { file = 0x8e2cc88 "bug-example.cc", line = xx (i.e. LocSet x;) } (If the SetData/LocSet constructor fails, then the superclass destructors must be called to clean up - the compiler therefore needs to synthesize ~hash_set). For EG2, ~hash_set is not declared until instantiate_pending_templates (called from finish_file): (gdb) c Breakpoint 1, lazily_declare_fn (sfk=sfk_destructor, type=0x41746c3c) at ../../gcc/cp/method.c:1055 (gdb) p input_location $13 = { file = 0x8e5cc40 "bug-example.h", line = xx (i.e. SetData(void) {i = 1;}) } Since "bug-example.h" contains #pragma interface this does not get compiled. It should, since it really comes from the "hash_set" header, which does not have #pragma interface. I have a very comple example in which this warning actually leads to a linker error, but in this small example I have not yet worked out how to make a destructor call which does not cause ~hash_set to be properly instantiated - but believe me, it can and does happen. ===================== */ main() { #if defined(EG1) LocSet x; int i=1; x.insert(&i); #else LocSet *x = new LocSet; int i=1; x->insert(&i); #endif } -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=21280