For the program below, g++ 3.4 does not emit code for RunState::runcallback, if compiled with -O3: $ g++ -O3 -o x x.cc /tmp/cc4LLDSK.o: In function `main': /tmp/cc4LLDSK.o(.text+0x1a): undefined reference to `RunState::runcallback()' collect2: ld returned 1 exit status $ $ g++ -c -O3 x.cc $ nm -Bo x.o x.o:00000000 T _Z1aPFvvE x.o: U _ZN8RunState11runcallbackEv x.o: U __gxx_personality_v0 x.o:00000010 T main $ Environment: System: Linux karma 2.4.19-emp_2419p5a829i #1 Tue Sep 3 17:42:17 EST 2002 i686 i686 i386 GNU/Linux Architecture: i686 <machine, os, target, libraries (multiple lines)> host: i686-pc-linux-gnu build: i686-pc-linux-gnu target: i686-pc-linux-gnu configured with: ../gcc/configure --prefix=/usr/local/gcc --enable-threads=posix --enable-long-long --enable-languages=c,c++,f77 : (reconfigured) : (reconfigured) : (reconfigured) : (reconfigured) : (reconfigured) : (reconfigured) : (reconfigured) : (reconfigured) : (reconfigured) : (reconfigured) : (reconfigured) : (reconfigured) : (reconfigured) : (reconfigured) : (reconfigured) : (reconfigured) : (reconfigured) : (reconfigured) : (reconfigured) : (reconfigured) : (reconfigured) How-To-Repeat: Compile with -O3: ----------------------------------------------------------------- void a (void (*f)()) { f(); } struct RunState { static void runcallback() { } static void wait() { a (runcallback); } }; int main() { RunState::wait(); return 0; } -----------------------------------------------------------------
Fix: <how to correct or work around the problem, if known (multiple lines)>
Confirmed. It is a unit-at-a-time problem, since if I specify -fno-unit-at-a-time, the problem goes away. That also implies that it is not related to PR 10804 and PR 10384 that seem to be similar, but predate unit-at-a-time (and don't benefit from giving that flag). W.
It looks like if the function is referenced in not in a call, unit-at-a-time does not mark the function as being used as gcc does not emit it.
Jan, this looks like a case you really want to take on.
The regression in PR 11530 was introduced or exposed by this patch (perhaps obvious, but this confirms that it wasn't caused a later change): --- gcc/gcc/ChangeLog --- Wed Jul 2 02:12:51 CEST 2003 Jan Hubicka <jh@suse.cz> * cgraphunit.c (cgraph_finalize_function): Set finalized. (cgraph_finalize_function): Do not examine inlinablility. (cgraph_finalize_compilation_unit): Do it here. * cgraph.h (cgraph_local_info): Add finalized field. --- gcc/gcc/cp/ChangeLog --- Wed Jul 2 00:36:48 CEST 2003 Jan Hubicka <jh@suse.cz> * decl2.c (defer_fn): Set DECL_DEFER_OUTPUT. (finish-file): Do not process function with DECL_DEFER_OUTPUT clear; clear DECL_DEFER_OUTPUT once function is processed; avoid flags massaging. * cp-tree.h (DECL_NEEDED_P): Support unit-at-a-time (expand_or_defer_fn): Declare. (lower_function): Declare. * decl.c (start_cleanup_fn): Use expand_or_defer_fn. * decl2.c: Include cgraph.h and varpool.h (maybe_emit_vtables): Make explicit instantations as needed. (mark_member_pointers, lower_function): New functions. (finish_file): Do unit-at-a-time. * method.c (synthesize_method): Use expand_or_defer_fn. * optimize.c (maybe_clone_body): Use expand_or_defer_fn. * parser.c (cp_parser_function_definition_after_decl): Use expand_or_defer_fn. * pt.c (instantiate_decl): Likewise. * semantics.c: Include cgraph.h (expand_or_defer_fn): Break out from ... (expand_body): ... here; deal with unit-at-a-time. * cp-lang.c (LANG_HOOKS_CALLGRAPH_EXPAND_FUNCTION, LANG_HOOKS_CALLGRAPH_LOWER_FUNCTION): Define. The regression hunt used the submitter's test case on i686-pc-linux-gnu compiled with -O3.
Subject: Bug 11530 CVSROOT: /cvs/gcc Module name: gcc Changes by: mmitchel@gcc.gnu.org 2003-07-29 01:57:48 Modified files: gcc/cp : ChangeLog parser.c semantics.c gcc/testsuite : ChangeLog Added files: gcc/testsuite/g++.dg/opt: call1.C Log message: PR c++/11530 * parser.c (cp_parser_postfix_expression): Do not call mark_used. * semantics.c (finish_id_expression): Call mark_used for all declarations. PR c++/11530 * g++.dg/opt/call1.C: New test. Patches: http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/ChangeLog.diff?cvsroot=gcc&r1=1.3564&r2=1.3565 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/parser.c.diff?cvsroot=gcc&r1=1.90&r2=1.91 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/semantics.c.diff?cvsroot=gcc&r1=1.337&r2=1.338 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/ChangeLog.diff?cvsroot=gcc&r1=1.2926&r2=1.2927 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/opt/call1.C.diff?cvsroot=gcc&r1=NONE&r2=1.1
Fixed by the patch above: 2003-07-28 Mark Mitchell PR c++/11530 * parser.c (cp_parser_postfix_expression): Do not call mark_used. * semantics.c (finish_id_expression): Call mark_used for all declarations. Which already included a test.