This bug report may be related to bug 20584, but I've got standalone compilable code that not only produces a warning, but also fails to link. File t.h: #pragma interface template<class T> struct C { explicit C(const T& t) : a(t) { } virtual ~C() { } T a; }; File f.cc: #include "t.h" struct A { A() { } virtual ~A() { } }; int main() { A a; C<A> c(a); } > g++ -g -Wall f.cc t.h:7: warning: inline function 'A::A(const A&)' used but never defined /tmp/ccM01LV4.o(.gnu.linkonce.t._ZN1CI1AEC1ERKS0_+0x21): In function `C<A>::C(A const&)': /home/jmaurer/IS/isgbe/servers/kfi/f.cc:12: undefined reference to `A::A(A const&)' It used to work with gcc 3.4.3. At the very least, the warning message should have an instantiation backtrace so that the user knows that the "used" comes from the instantiation of C<A>.
*** Bug 20584 has been marked as a duplicate of this bug. ***
Confirmed.
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 }
Created attachment 8769 [details] Removed some code which improves diagnostics but breaks instantiation
Following up my earlier comment: It appears that some code, which is intended to improve the user diagnostics, can in fact break the template instantiation process, for the reason stated in the comment which you can find in the patch FIX1.
*** Bug 21306 has been marked as a duplicate of this bug. ***
Mark you added the code to lazy create the deconstructors, would you look into this problem?
Bug 21306 is not the same bug. The attached patch FIX1 fixes the test cases for this bug, but not for 21306 - you will need to look at the test case for that bug.
Subject: Bug 21280 CVSROOT: /cvs/gcc Module name: gcc Branch: gcc-4_0-branch Changes by: nathan@gcc.gnu.org 2005-06-02 17:31:11 Modified files: gcc/cp : ChangeLog Make-lang.in decl.c decl2.c method.c gcc/testsuite : ChangeLog gcc/testsuite/g++.dg/init: ctor4.C gcc/testsuite/g++.old-deja/g++.bob: inherit2.C gcc/testsuite/g++.old-deja/g++.bugs: 900205_04.C gcc/testsuite/g++.old-deja/g++.jason: opeq3.C gcc/testsuite/g++.old-deja/g++.pt: assign1.C crash20.C Added files: gcc/testsuite/g++.dg/opt: interface2.C interface2.h Log message: cp: PR c++/21280 * Make-lang.in (method.o): Add diagnostic.h * decl.c (start_preparsed_function): Use decl's location for file info. * decl2.c (cp_finish_file): Set input_location before synthesizing a function. (mark_used): When deferring a synthesized function, save current location. Do not set function's location when actually synthesizing it. * method.c: #include diagnostic.h. (synthesize_method): Set the functions source location. Show needed location if errors are emitted. testsuite: PR c++/21280 * g++.dg/opt/interface2.h: New. * g++.dg/opt/interface2.C: New. * g++.dg/init/ctor4.C: Adjust error lines. * g++.old-deja/g++.bob/inherit2.C: Likewise. * g++.old-deja/g++.bugs/900205_04.C: Likewise. * g++.old-deja/g++.jason/opeq3.C: Likewise. * g++.old-deja/g++.pt/assign1.C: Likewise. * g++.old-deja/g++.pt/crash20.C: Likewise. Patches: http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/ChangeLog.diff?cvsroot=gcc&only_with_tag=gcc-4_0-branch&r1=1.4648.2.53&r2=1.4648.2.54 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/Make-lang.in.diff?cvsroot=gcc&only_with_tag=gcc-4_0-branch&r1=1.200.8.1&r2=1.200.8.2 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/decl.c.diff?cvsroot=gcc&only_with_tag=gcc-4_0-branch&r1=1.1371.2.12&r2=1.1371.2.13 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/decl2.c.diff?cvsroot=gcc&only_with_tag=gcc-4_0-branch&r1=1.770.2.1&r2=1.770.2.2 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/method.c.diff?cvsroot=gcc&only_with_tag=gcc-4_0-branch&r1=1.322.4.2&r2=1.322.4.3 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/ChangeLog.diff?cvsroot=gcc&only_with_tag=gcc-4_0-branch&r1=1.5084.2.220&r2=1.5084.2.221 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/opt/interface2.C.diff?cvsroot=gcc&only_with_tag=gcc-4_0-branch&r1=NONE&r2=1.1.2.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/opt/interface2.h.diff?cvsroot=gcc&only_with_tag=gcc-4_0-branch&r1=NONE&r2=1.1.2.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/init/ctor4.C.diff?cvsroot=gcc&only_with_tag=gcc-4_0-branch&r1=1.1&r2=1.1.6.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.old-deja/g++.bob/inherit2.C.diff?cvsroot=gcc&only_with_tag=gcc-4_0-branch&r1=1.6&r2=1.6.76.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.old-deja/g++.bugs/900205_04.C.diff?cvsroot=gcc&only_with_tag=gcc-4_0-branch&r1=1.5&r2=1.5.4.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.old-deja/g++.jason/opeq3.C.diff?cvsroot=gcc&only_with_tag=gcc-4_0-branch&r1=1.4&r2=1.4.76.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.old-deja/g++.pt/assign1.C.diff?cvsroot=gcc&only_with_tag=gcc-4_0-branch&r1=1.3&r2=1.3.76.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.old-deja/g++.pt/crash20.C.diff?cvsroot=gcc&only_with_tag=gcc-4_0-branch&r1=1.4&r2=1.4.76.1
Subject: Bug 21280 CVSROOT: /cvs/gcc Module name: gcc Branch: gcc-4_0-branch Changes by: nathan@gcc.gnu.org 2005-06-02 17:33:36 Modified files: libstdc++-v3 : ChangeLog libstdc++-v3/testsuite/27_io/ios_base/cons: assign_neg.cc copy_neg.cc Log message: PR c++/21280 * testsuite/27_io/ios_base/cons/assign_neg.cc: Adjust expected errors. * testsuite/27_io/ios_base/cons/copy_neg.cc: Likewise. Patches: http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/ChangeLog.diff?cvsroot=gcc&only_with_tag=gcc-4_0-branch&r1=1.2917.2.57&r2=1.2917.2.58 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/testsuite/27_io/ios_base/cons/assign_neg.cc.diff?cvsroot=gcc&only_with_tag=gcc-4_0-branch&r1=1.11&r2=1.11.16.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/testsuite/27_io/ios_base/cons/copy_neg.cc.diff?cvsroot=gcc&only_with_tag=gcc-4_0-branch&r1=1.11&r2=1.11.16.1
Subject: Bug 21280 CVSROOT: /cvs/gcc Module name: gcc Changes by: nathan@gcc.gnu.org 2005-06-02 17:48:58 Modified files: libstdc++-v3 : ChangeLog libstdc++-v3/testsuite/27_io/ios_base/cons: assign_neg.cc copy_neg.cc Log message: PR c++/21280 * testsuite/27_io/ios_base/cons/assign_neg.cc: Adjust expected errors. * testsuite/27_io/ios_base/cons/copy_neg.cc: Likewise. Patches: http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/ChangeLog.diff?cvsroot=gcc&r1=1.3026&r2=1.3027 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/testsuite/27_io/ios_base/cons/assign_neg.cc.diff?cvsroot=gcc&r1=1.11&r2=1.12 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/testsuite/27_io/ios_base/cons/copy_neg.cc.diff?cvsroot=gcc&r1=1.11&r2=1.12
2005-06-02 Nathan Sidwell <nathan@codesourcery.com> PR c++/21280 * Make-lang.in (method.o): Add diagnostic.h * decl.c (start_preparsed_function): Use decl's location for file info. * decl2.c (cp_finish_file): Set input_location before synthesizing a function. (mark_used): When deferring a synthesized function, save current location. Do not set function's location when actually synthesizing it. * method.c: #include diagnostic.h. (synthesize_method): Set the functions source location. Show needed location if errors are emitted.
Subject: Bug 21280 CVSROOT: /cvs/gcc Module name: gcc Changes by: nathan@gcc.gnu.org 2005-06-02 17:52:29 Modified files: gcc/cp : ChangeLog Make-lang.in decl.c decl2.c method.c gcc/testsuite : ChangeLog gcc/testsuite/g++.dg/init: ctor4.C gcc/testsuite/g++.old-deja/g++.bob: inherit2.C gcc/testsuite/g++.old-deja/g++.bugs: 900205_04.C gcc/testsuite/g++.old-deja/g++.jason: opeq3.C gcc/testsuite/g++.old-deja/g++.pt: assign1.C crash20.C Added files: gcc/testsuite/g++.dg/opt: interface2.C interface2.h Log message: cp: PR c++/21280 * Make-lang.in (method.o): Add diagnostic.h * decl.c (start_preparsed_function): Use decl's location for file info. * decl2.c (cp_finish_file): Set input_location before synthesizing a function. (mark_used): When deferring a synthesized function, save current location. Do not set function's location when actually synthesizing it. * method.c: #include diagnostic.h. (synthesize_method): Set the functions source location. Show needed location if errors are emitted. testsuite: PR c++/21280 * g++.dg/opt/interface2.h: New. * g++.dg/opt/interface2.C: New. * g++.dg/init/ctor4.C: Adjust error lines. * g++.old-deja/g++.bob/inherit2.C: Likewise. * g++.old-deja/g++.bugs/900205_04.C: Likewise. * g++.old-deja/g++.jason/opeq3.C: Likewise. * g++.old-deja/g++.pt/assign1.C: Likewise. * g++.old-deja/g++.pt/crash20.C: Likewise. Patches: http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/ChangeLog.diff?cvsroot=gcc&r1=1.4770&r2=1.4771 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/Make-lang.in.diff?cvsroot=gcc&r1=1.203&r2=1.204 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/decl.c.diff?cvsroot=gcc&r1=1.1401&r2=1.1402 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/decl2.c.diff?cvsroot=gcc&r1=1.783&r2=1.784 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/method.c.diff?cvsroot=gcc&r1=1.330&r2=1.331 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/ChangeLog.diff?cvsroot=gcc&r1=1.5578&r2=1.5579 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/opt/interface2.C.diff?cvsroot=gcc&r1=1.1&r2=1.2 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/opt/interface2.h.diff?cvsroot=gcc&r1=1.1&r2=1.2 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/init/ctor4.C.diff?cvsroot=gcc&r1=1.1&r2=1.2 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.old-deja/g++.bob/inherit2.C.diff?cvsroot=gcc&r1=1.6&r2=1.7 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.old-deja/g++.bugs/900205_04.C.diff?cvsroot=gcc&r1=1.5&r2=1.6 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.old-deja/g++.jason/opeq3.C.diff?cvsroot=gcc&r1=1.4&r2=1.5 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.old-deja/g++.pt/assign1.C.diff?cvsroot=gcc&r1=1.3&r2=1.4 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.old-deja/g++.pt/crash20.C.diff?cvsroot=gcc&r1=1.4&r2=1.5