The following input: class A { public: A(); virtual void find() {} };
static void foo(A &a) { a.find(); } void bar() { A a; foo(a); } when compiled with gcc-4.0.3, 4.0.4, 4.3.3 and 4.4.0 on HP-UX with -O will produce assembly code that contains a call to find() but no definition and no IMPORT: $ gcc-4.4.0/bin/g++ -S -O repro.cc $ grep 4find repro.s bl _ZN1A4findEv,%r2 Contrast with A::A(), which has both a call and an IMPORT: $ grep AC1 repro.s bl _ZN1AC1Ev,%r2 .IMPORT _ZN1AC1Ev,CODE The above input is approximately minimal; removing or changing any of the features will make the problem disappear, typically by causing find() to be completely inlined into the call site. Interestingly, gcc-4.1.2 does not show a problem on this particular input, although my recollection is it was showing the problem on a larger variant. I do not know where along the minimization process gcc-4.1.2 stopped reproducing. The lack of an IMPORT despite no definition is particularly nasty, because 'nm' simply reports it as an undefined symbol, but the HP-UX linker refuses to link the result into an executable when presented with another object file that contains the definition: $ g++ -c -O repro.cc $ g++ -c -O rest.cc # defines A::A() and main() $ g++ repro.o rest.o /usr/ccs/bin/ld: Unsatisfied symbols: A::find() (first referenced in repro.o) (data) collect2: ld returned 1 exit status $ nm repro.o | grep 4find U _ZN1A4findEv $ nm rest.o | grep 4find 00000000 W _ZN1A4findEv The above is with GNU 'as' 2.15 and 2.17 (same result). When using the HP-UX assembler version "HP92453-03 UX.11.01.17 PA-RISC 2.0 Assembler" (which only accepts gcc-4.0.x output), it more helpfully notices the missing IMPORT: as: error 7403: undefined label - _ZN1A4findEv (7403) Of course, I didn't discover the IMPORT issue until after some hours of searching for an explanation to the mysterious linker complaint. It would be nice if GNU 'as' would realize that it is creating a .o file that cannot be linked. For completeness, the HP-UX linker version is "92453-07 linker linker ld B.11.63 071126". The IMPORT anomaly is specific to HP-UX, but the failure to emit a definition of an inline is not. On linux/x86_64 with gcc-4.0.3, for example, repro.o again has a call but no definition, but is able to link by using the definition from rest.o because there is no IMPORT concept. I find it suspicious that the compiler would ever choose to emit a direct call to a defined inline function without also including that function's definition; but the C++ ODR guarantees the compiler it will see the class definition again, including the method body, in the translation unit containing the definition of A::A(), so the omission is not by itself necessarily indicative of a bug. It's worth noting that the presence of a direct call to find() means the compiler figured out it is A::find() being called, despite that method being virtual. I suspect the mechanism that does that may be partly to blame. That's the reason for including "resolved" in this bug's title. -- Summary: failure to emit resolved inline virtual function definition or IMPORT on HP-UX with -O Product: gcc Version: 4.4.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: smcpeak at coverity dot com GCC build triplet: hppa2.0w-hp-hpux11.11 GCC host triplet: hppa2.0w-hp-hpux11.11 GCC target triplet: hppa2.0w-hp-hpux11.11 http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40490