Bug 45721 - [4.6 Regression] ICE: in function_and_variable_visibility, at ipa.c:673 with -flto
Summary: [4.6 Regression] ICE: in function_and_variable_visibility, at ipa.c:673 with ...
Alias: None
Product: gcc
Classification: Unclassified
Component: lto (show other bugs)
Version: 4.6.0
: P1 normal
Target Milestone: 4.6.0
Assignee: Jan Hubicka
Keywords: lto
Depends on:
Reported: 2010-09-18 18:00 UTC by Zdenek Sojka
Modified: 2011-01-11 17:41 UTC (History)
2 users (show)

See Also:
Host: x86_64-pc-linux-gnu
Target: x86_64-pc-linux-gnu
Known to work:
Known to fail:
Last reconfirmed: 2010-11-04 11:16:03


Note You need to log in before you can comment on or make changes to this bug.
Description Zdenek Sojka 2010-09-18 18:00:58 UTC
Compiler output:
$ gcc -flto -r -nostdlib file[12].c
lto1: internal compiler error: in function_and_variable_visibility, at ipa.c:673
Please submit a full bug report,
with preprocessed source if appropriate.
See <http://gcc.gnu.org/bugs.html> for instructions.
lto-wrapper: /mnt/svn/gcc-trunk/binary-164287-lto-fortran-checking-yes-rtl-df/bin/gcc returned 1 exit status
collect2: lto-wrapper returned 1 exit status

------ file1.c ------
extern void baz(void);
void *y = (void *)baz;
------ file2.c ------
static void bar(void) __attribute__ ((__weakref__("baz")));
void *x = (void *)bar;

I don't know if this is valid, but originally those were valid C and C++ files including only system libraries.

Tested revisions:
r164287 - crash
r163636 - crash
r161659 - OK
r159696 - OK
r153685 - OK
4.5 r163761 - OK
Comment 1 Richard Biener 2010-11-04 11:16:03 UTC
Comment 2 Richard Biener 2010-11-11 12:28:42 UTC
More complete testcase:

--- file1.c ----
void baz(void) {}
void *y = (void *)baz;
int main () { return 0; }

--- file2.c ----
static void bar(void) __attribute__ ((weakref("baz")));
void *x = (void *)bar;

which still ICEs with a trivial patch I had (that fixed the original one).

It shows that we somehow fail to mark baz as needed even though it is
referenced by y.  And of course we fail to mark it needed by the
alias as well.

One reason may be that we don't have a cgraph node for baz in file2.o
(nor do we have one if declaring baz).  OTOH when reading the cgraph
node for baz it shows that it is !needed which is obviously wrong.
ref_list of the cgraph node for baz is empty.  The ref_list for
y contains three times(!??):
 fn:baz/0 (addr) fn:baz/0 (addr) fn:baz/0 (addr)

then 2nd and 3rd come from

#5  0x0000000000d075f0 in cgraph_process_new_functions ()
    at /space/rguenther/src/svn/trunk/gcc/cgraphunit.c:219
219       varpool_analyze_pending_decls ();
#6  0x00000000008fae86 in execute_one_pass (pass=0x1722900)
    at /space/rguenther/src/svn/trunk/gcc/passes.c:1596
1596        cgraph_process_new_functions ();

as somehow the decl stays in pending state?  It does because

Old value = (struct varpool_node *) 0x0
New value = (struct varpool_node *) 0x7ffff5cf8138
varpool_enqueue_needed_node (node=0x7ffff5cf8138)
    at /space/rguenther/src/svn/trunk/gcc/varpool.c:303
303       notice_global_symbol (node->decl);
(gdb) up
#1  0x0000000000d7367f in varpool_mark_needed_node (node=0x7ffff5cf8138)
    at /space/rguenther/src/svn/trunk/gcc/varpool.c:315
315         varpool_enqueue_needed_node (node);

re-queues it.  Why if it is already analyzed (and why did it become
!needed again?  Should varpool_analyze_pending_decls not re-analyze
analyzed nodes?)

These are, of course, just unrelated problems.

Still for some reason the cgraph node is not needed:

Breakpoint 1, fancy_abort (
    file=0x113abc8 "/space/rguenther/src/svn/trunk/gcc/ipa.c", line=783, 
    function=0x113ae20 "function_and_variable_visibility")
    at /space/rguenther/src/svn/trunk/gcc/diagnostic.c:881
881       internal_error ("in %s, at %s:%d", function, trim_filename (file), line);
(gdb) up
#1  0x0000000000c82296 in function_and_variable_visibility (
    whole_program=0 '\000') at /space/rguenther/src/svn/trunk/gcc/ipa.c:782
warning: Source file is more recent than executable.
782               gcc_assert (node->needed);
(gdb) p node->ref_list
$11 = {references = 0x0, refering = 0x17739e0}
(gdb) p node->ref_list->refering
$12 = (VEC_ipa_ref_ptr_heap *) 0x17739e0
(gdb) p node->ref_list->refering->base.vec[0]->refering.varpool_node->needed
$13 = 1

but it has a referer that is needed.

Honza - please investigate this - I'm lost in the maze.
Comment 3 Jan Hubicka 2010-11-11 14:16:07 UTC
handling of weaks and weakrefs is indeed deeply broken with LTO.  I plan to look into it after pushing more of the stuff
I don't want to get into mainline too late in stage3. That is the inliner bits and -flto changes. Hopefully early next week
(I am flying during the weekend).

Comment 4 Jan Hubicka 2010-12-14 16:32:39 UTC
Comment 5 Jan Hubicka 2011-01-06 22:26:42 UTC
Mine, testing patch.
Comment 6 Jan Hubicka 2011-01-07 18:43:49 UTC
path posted http://gcc.gnu.org/ml/gcc-patches/2011-01/msg00375.html
Comment 7 Jan Hubicka 2011-01-11 17:29:57 UTC
Author: hubicka
Date: Tue Jan 11 17:29:52 2011
New Revision: 168666

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=168666

	PR lto/45721
	PR lto/45375
	* tree.h (symbol_alias_set_t): Move typedef here from varasm.c
	(symbol_alias_set_destroy, symbol_alias_set_contains,
	propagate_aliases_backward): Declare.
	* lto-streamer-out.c (struct sets): New sturcture.
	(trivally_defined_alias): New function.
	(output_alias_pair_p): Rewrite.
	(output_unreferenced_globals): Fix output of alias pairs.
	(produce_symtab): Likewise.
	* ipa.c (function_and_variable_visibility): Set weak alias destination
	as needed in lto.
	* varasm.c (symbol_alias_set_t): Remove.
	(symbol_alias_set_destroy): Export.
	(propagate_aliases_forward, propagate_aliases_backward): New functions
	based on ...
	(compute_visible_aliases): ... this one; remove.
	(trivially_visible_alias): New
	(trivially_defined_alias): New.
	(remove_unreachable_alias_pairs): Rewrite.
	(finish_aliases_1): Reorganize code checking if alias is defined.
	* passes.c (rest_of_decl_compilation): Do not call assemble_alias when
	in LTO mode.

	* lto.c (partition_cgraph_node_p, partition_varpool_node_p): Weakrefs are
	not partitioned.

	* testsuite/gcc.dg/lto/pr45721_1.c: New file.
	* testsuite/gcc.dg/lto/pr45721_0.c: New file.

Comment 8 Jan Hubicka 2011-01-11 17:41:07 UTC