This is the mail archive of the gcc-bugs@gcc.gnu.org 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]

virtual base classes break -frepo


The -frepo flag doesn't seem to work when templates have virtual base
classes.  The compiler ends up failing to generate a vtable.

The attached program demonstrates the problem.  With the latest
version of the compiler (egcs-2.93.02 19990118) on Linux, I get:

% c++ -frepo -Wall -c repo2.C && c++ -frepo repo2.o
collect: recompiling repo2.C
collect: relinking
repo2.o: In function `refcounted<foo>::refcounted(int)':
repo2.o(.text+0x27): undefined reference to `refcounted<foo>::refcount virtual table'
collect2: ld returned 1 exit status

A slightly older version of the compiler on Solaris exhibits a similar
problem, except it doesn't even bother trying to recompile:

% c++ -frepo -Wall -c repo2.C && c++ -frepo repo2.o
Undefined                       first referenced
 symbol                             in file
refcounted<foo>::refcount virtual tablerepo2.o
ld: fatal: Symbol referencing errors. No output written to a.out
collect2: ld returned 1 exit status

On OpenBSD, which seems particularly bad with vtables under -frepo, I
get the error 3 times (with todays compiler):

% c++ -frepo -Wall -c repo2.C && c++ -frepo repo2.o
repo2.o: Undefined symbol `refcounted<foo>::refcount virtual table' referenced from text segment
repo2.o: Undefined symbol `refcounted<foo>::refcount virtual table' referenced from text segment
repo2.o: Undefined symbol `refcounted<foo>::refcount virtual table' referenced from text segment
collect2: ld returned 1 exit status

Incidentally, while demangled linker errors are generally what users
want, it might be nice to have an option to turn off demangling of
linker error messages.  In cases like this I would like to compare the
output of nm and the contents of the .rpo files with the actual linker
messages.  One can generally figure this out "backwards" starting from
nm and using c++ filt, but when the mangling itself is somewhat
suspect (as under OpenBSD where underscores get dropped), raw link
errors would be helpful.

Thanks,
David

==

/*
 * Since this now seems to matter:
 *
 * Copyright 1999 David Mazieres.  No other person or organization
 * owns any part of this software.  Permission hereby granted to
 * include this program, modified versions, or derivative works in any
 * complier test suite distributed in any form under any license.
 * Permission is also granted to remove this copyright notice if the
 * compiler test suite is distributed under a license compatible with
 * version 2 or later of the GPL.  Permission also granted to use and
 * distribute this code under the GPL.  If the Free Software
 * Foundation ever publishes a document entitled something like
 * "suggested license for code snippets submitted as part of compiler
 * bug reports," then permission is additionally granted to use and
 * distribute the code under the terms of that document.  Blah, blah,
 * blah.  In short, no one is going to sue you for putting this code
 * in the egcs suite, even if you remove this wordy copyright.
 * Guaranteed.
 */

#include <sys/types.h>

#define New new

struct refcount {
  int cnt;
  void refcount_inc () { cnt++; }
  void refcount_dec () { if (!--cnt) delete this; }
  refcount () : cnt (0) {}
  virtual ~refcount () {}
};

template<class T>
struct refcounted
  : virtual public refcount, public T
{
  refcounted () {}
  template<class A1>
  refcounted (const A1 &a1)
    : T (a1) {}
  template<class A1, class A2>
  refcounted (const A1 &a1, const A2 &a2)
    : T (a1, a2) {}
  template<class A1, class A2, class A3>
  refcounted (const A1 &a1, const A2 &a2, const A3 &a3)
    : T (a1, a2, a3) {}
  template<class A1, class A2, class A3, class A4>
  refcounted (const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4)
    : T (a1, a2, a3, a4) {}
};

template<class T>
struct ref {
  refcount *c;
  T *p;

  void refcount_inc () const { c->refcount_inc (); }
  void refcount_dec () const { c->refcount_dec (); }

  ref (const ref &r)
    : c (r), p (r) { refcount_inc (); }
  template<class U> ref (const U &r)
    : c (r), p (r) { refcount_inc (); }
  const ref &operator= (const ref &r)
    { r.refcount_inc (); refcount_dec (); c = r.c; p = r.p; return *this; }

  operator refcount *() const { return c; }
  operator T *() const { return p; }
  T *operator-> () const { return p; }
  T &operator* () const { return *p; }
};

struct foo {};

int
main ()
{
  ref<foo> fp (new refcounted<foo>);
  return sizeof (fp);
}


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