This is the mail archive of the mailing list for the GCC project.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug c++/21280] [4.0/4.1 Regression] #pragma interface, templates, and "inline function used but never defined"

------- 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++ (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;
  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 ----------------------------------------------------------

// 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
	stop only if !({<text variable, no debug info>} 0x599b60 <strncmp>)
(type->>>, "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
(gdb) p type->>>
$10 = (const unsigned char *) 0x8e6706a
"hash_set<Loc*,Loc_hash,Loc_eq,std::allocator<Loc*> >"
(gdb) p input_location
$11 = {
  file = 0x8e2cc88 "", 
  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

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
(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.
===================== */

#if defined(EG1)
  LocSet x;
  int i=1;
  LocSet *x = new LocSet;
  int i=1;


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]