Bug 21280 - [4.0/4.1 Regression] #pragma interface, templates, and "inline function used but never defined"
Summary: [4.0/4.1 Regression] #pragma interface, templates, and "inline function used ...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 4.0.0
: P2 normal
Target Milestone: 4.0.1
Assignee: Nathan Sidwell
URL:
Keywords: diagnostic
: 20584 21306 (view as bug list)
Depends on:
Blocks:
 
Reported: 2005-04-29 08:59 UTC by Jens Maurer
Modified: 2005-06-02 17:51 UTC (History)
6 users (show)

See Also:
Host: i686-pc-linux-gnu
Target: i686-pc-linux-gnu
Build: i686-pc-linux-gnu
Known to work:
Known to fail:
Last reconfirmed: 2005-06-02 11:52:55


Attachments
Removed some code which improves diagnostics but breaks instantiation (388 bytes, patch)
2005-04-30 17:26 UTC, Peter Wainwright
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Jens Maurer 2005-04-29 08:59:43 UTC
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>.
Comment 1 Andrew Pinski 2005-04-29 12:21:59 UTC
*** Bug 20584 has been marked as a duplicate of this bug. ***
Comment 2 Andrew Pinski 2005-04-29 12:23:49 UTC
Confirmed.
Comment 3 Peter Wainwright 2005-04-30 07:37:04 UTC
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
}
Comment 4 Peter Wainwright 2005-04-30 17:26:45 UTC
Created attachment 8769 [details]
Removed some code which improves diagnostics but breaks instantiation
Comment 5 Peter Wainwright 2005-04-30 17:29:56 UTC
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.
Comment 6 Andrew Pinski 2005-04-30 21:14:09 UTC
*** Bug 21306 has been marked as a duplicate of this bug. ***
Comment 7 Andrew Pinski 2005-04-30 23:42:18 UTC
Mark you added the code to lazy create the deconstructors, would you look into this problem?
Comment 8 Peter Wainwright 2005-05-05 17:23:07 UTC
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.

Comment 9 GCC Commits 2005-06-02 17:31:20 UTC
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

Comment 10 GCC Commits 2005-06-02 17:33:41 UTC
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

Comment 11 GCC Commits 2005-06-02 17:49:10 UTC
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

Comment 12 Nathan Sidwell 2005-06-02 17:51:49 UTC
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.
Comment 13 GCC Commits 2005-06-02 17:52:36 UTC
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