Bug 15700 - [4.0 Regression] [unit-at-a-time] Inlining problem leads to miscompilation of glibc
Summary: [4.0 Regression] [unit-at-a-time] Inlining problem leads to miscompilation of...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: middle-end (show other bugs)
Version: 4.0.0
: P2 normal
Target Milestone: 4.0.0
Assignee: Richard Henderson
URL:
Keywords: wrong-code
: 18656 20167 (view as bug list)
Depends on:
Blocks:
 
Reported: 2004-05-28 07:15 UTC by Andreas Jaeger
Modified: 2005-03-16 21:51 UTC (History)
7 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2005-03-14 17:08:49


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Andreas Jaeger 2004-05-28 07:15:03 UTC
glibc cannot be compiled by current 3.5 mainline on AMD64 (but same
situation on ia64).  I've reduced the error to the following example:

extern int __internal_getnetgrent_r (void);

static int
internal_getnetgrent_r (void)
{
  return 1;
}

extern __typeof (internal_getnetgrent_r) __internal_getnetgrent_r __attribute__
((alias ("internal_getnetgrent_r")));

int
test (void)
{
  return internal_getnetgrent_r ();
  
}

With GCC 3.5 of today I get internal_getnetgrent_r undefined:

reger:/tmp:[0]$ /opt/gcc/3.5-devel/bin/gcc -O2 -c test.c
reger:/tmp:[0]$ nm test.o
                 U internal_getnetgrent_r
0000000000000000 T test
reger:/tmp:[0]$ /opt/gcc/3.5-devel/bin/gcc -O2 -c test.c
reger:/tmp:[0]$ nm test.o
                 U internal_getnetgrent_r
0000000000000000 T test

But older GCC versions (3.3 and 3.4.0) produce:

reger:/tmp:[0]$ gcc -O2 -c test.c
reger:/tmp:[0]$ nm test.o
0000000000000000 T __internal_getnetgrent_r
0000000000000000 t internal_getnetgrent_r
0000000000000010 T test
reger:/tmp:[0]$ /opt/gcc/3.4-devel/bin/gcc -O2 -c test.c
reger:/tmp:[0]$ nm test.o
0000000000000000 T __internal_getnetgrent_r
0000000000000000 t internal_getnetgrent_r
0000000000000010 T test

Is this a bug in glibc or in GCC?

3.5 inlines the code but 3.4 not, the difference in the assembler is:

--- test-3.5.s      2004-05-27 17:40:11.255202552 +0200
+++ test-3.4.s  2004-05-27 17:39:51.789864313 +0200
@@ -2,14 +2,20 @@
 .globl __internal_getnetgrent_r
        .set    __internal_getnetgrent_r,internal_getnetgrent_r
        .text
-       .align 4
+       .p2align 4,,15
+       .type   internal_getnetgrent_r, @function
+internal_getnetgrent_r:
+.LFB2:
+       movl    $1, %eax
+       ret
+.LFE2:
+       .size   internal_getnetgrent_r, .-internal_getnetgrent_r
        .p2align 4,,15
 .globl test
        .type   test, @function
 test:
 .LFB3:
-       movl    $1, %eax
-       ret
+       jmp     internal_getnetgrent_r
 .LFE3:
        .size   test, .-test
        .section        .eh_frame,"a",@progbits


It seems the following statement:
.set    __internal_getnetgrent_r,internal_getnetgrent_r

should not be emitted if the function is inlined.
Comment 1 Andreas Jaeger 2004-05-28 07:15:59 UTC
Jakub Jelinek commented on this one with:
IMHO it should be emitted no matter if it is inlined or not, but
if there is an (non-static) alias the function body for it needs to be
emitted as well.

Comment 2 Andrew Pinski 2004-05-28 17:08:34 UTC
Confirmed, an unit-at-a-time problem.
Comment 3 Serge Belyshev 2004-05-29 17:57:58 UTC
I can confirm this bug on i686-pc-linux-gnu
Comment 4 Jan Hubicka 2004-05-29 18:49:38 UTC
Subject: Re:  [3.5 Regression] [unit-at-a-time] Inlining problem leads to miscompilation of glibc

> 
> ------- Additional Comments From belyshev at lubercy dot com  2004-05-29 17:57 -------
> I can confirm this bug on i686-pc-linux-gnu

The problem is obviously that GCC decides to not compile the function.
I am not quite sure whether GCC should conclude that every aliased
function is implicitly __attribute__ ((used)) or whether GCC should know
how to avoid emitting the alias.
The first one is easier to implement so if there are no complains, I
will do the first.  But why glibc is renaming static symbol never used
by asm code at first place?

Honza
> 
> -- 
> 
> 
> http://gcc.gnu.org/bugzilla/show_bug.cgi?id=15700
> 
> ------- You are receiving this mail because: -------
> You are on the CC list for the bug, or are watching someone who is.
Comment 5 Serge Belyshev 2004-06-18 16:03:14 UTC
workaround: apply this patch to file libc/inet/getnetgrent_r.c and glibc will
work just fine.

------------------------------------------------------------------------------
--- getnetgrent_r.c.~1.24.~     2002-11-10 14:06:35.000000000 +0300
+++ getnetgrent_r.c     2004-06-18 17:50:48.073311536 +0400
@@ -133,7 +133,7 @@
   return status == NSS_STATUS_SUCCESS;
 }
 
-static int
+static int __attribute__((used))
 internal_setnetgrent (const char *group, struct __netgrent *datap)
 {
   /* Free list of all netgroup names from last run.  */
@@ -158,7 +158,7 @@
 }
 
 
-static void
+static void __attribute__((used))
 internal_endnetgrent (struct __netgrent *datap)
 {
   service_user *old_nip;
@@ -200,7 +200,7 @@
 }
 
 
-static int
+static int __attribute__((used))
 internal_getnetgrent_r (char **hostp, char **userp, char **domainp,
                          struct __netgrent *datap,
                          char *buffer, size_t buflen, int *errnop)
------------------------------------------------------------------------------
Comment 6 Andrew Pinski 2004-06-18 16:06:18 UTC
I think this comes down to the change over which uses decls instead of ASM names...
Comment 7 Andrew Pinski 2004-07-02 20:45:23 UTC
I actually think this is caused by Zack's patch to move away from asm name and to decls instead, so 
maybe there is a missing set_assembled_name somewhere.
Comment 8 Andrew Pinski 2004-07-02 20:55:51 UTC
Obviously I mean change_decl_assembler_name instead of SET_DECL_ASSEMBLER_NAME.

This looks to be c_static_assembler_name which uses SET_DECL_ASSEMBLER_NAME instead of 
change_decl_assembler_name, lets see if that fixes the problem.
Comment 9 Alexandre Oliva 2004-07-09 05:38:45 UTC
I think this is actually a broken assumption in glibc.  attribute alias expects
an assembly symbol name, not a C declaration name, which is made clear by the
need for mangled names in C++.  A declaration without linkage, such as that of a
static symbol, enables the compiler to choose whatever it likes for the asm
symbol name.
Comment 10 Andrew Pinski 2004-07-09 06:43:27 UTC
Lets see something like this happened when the first IMA patch went in, see <http://gcc.gnu.org/ml/
gcc-patches/2003-07/msg02424.html>.
Comment 11 Andrew Pinski 2004-07-18 06:56:51 UTC
This is a glibc bug, see <http://sources.redhat.com/ml/libc-alpha/2004-07/msg00020.html>.
Comment 12 Andrew Pinski 2004-11-24 20:32:50 UTC
*** Bug 18656 has been marked as a duplicate of this bug. ***
Comment 13 H.J. Lu 2004-11-24 21:31:52 UTC
I am not sure why it shouldn't work. Given

static void
foo_internal ()
{
}

extern void (*foo) ();
void
xxx ()
{
  foo = &foo_internal;
}

void
bar ()
{
  foo_internal ();
}

Gcc 4.0 has no problems inlining foo_internal and emitting its body at the
same time. The only difference here is the address of foo_internal vs. an
external alias of foo_internal. In fact, gcc 4.0 does the right thing for

static void
foo_internal ()
{
}

extern void (*foo) ();
void
xxx ()
{
  foo = &foo_internal;
}

extern __typeof (foo_internal) work __attribute__ ((alias ("foo_internal")));

void
bar ()
{
  foo_internal ();
}

Gcc 4.0 has to do inlining and emitting body of a static functon anyway. How
to make it to work with external alias?
Comment 14 Andrew Pinski 2004-11-24 21:37:50 UTC
Then mark the static function as used.  Again the problem is related to that gcc does not look into the 
string of alias period, except for when writting out the asm.
extern __typeof (foo_internal) work __attribute__ ((alias ("foo_internal")));
Comment 15 Andrew Pinski 2005-02-23 15:11:12 UTC
*** Bug 20167 has been marked as a duplicate of this bug. ***
Comment 16 Alexandre Oliva 2005-03-04 23:29:07 UTC
But GCC *does* look into the string in -funit-at-a-time mode.  It doens't only
in -fno-unit-at-a-time-mode, and so it fails to emit static functions that are
referenced in aliases.  It should behave the same regardless of unit-at-a-time.
Comment 17 Richard Henderson 2005-03-14 17:08:49 UTC
Mine.
Comment 18 GCC Commits 2005-03-16 17:15:27 UTC
Subject: Bug 15700

CVSROOT:	/cvs/gcc
Module name:	gcc
Changes by:	rth@gcc.gnu.org	2005-03-16 17:15:11

Modified files:
	gcc            : ChangeLog cgraphunit.c passes.c toplev.c tree.h 
	                 varasm.c 
	gcc/testsuite  : ChangeLog 
	gcc/testsuite/gcc.c-torture/compile: 20040323-1.c 
	gcc/testsuite/gcc.dg/weak: weak-3.c weak-9.c 
Added files:
	gcc/testsuite/gcc.dg: alias-3.c alias-4.c alias-5.c alias-6.c 

Log message:
	PR middle-end/15700
	* varasm.c (struct alias_pair): Rename from struct output_def_pair.
	(alias_pairs): Rename from output_defs.
	(find_decl_and_mark_needed): Split out from assemble_alias.
	(do_assemble_alias): New.
	(assemble_output_def): Remove.
	(finish_aliases_1, finish_aliases_2): New.
	(process_pending_assemble_output_defs): Remove.
	(assemble_alias): Defer aliases for which we don't yet have a
	non-external decl for the target symbol.
	* passes.c (rest_of_decl_compilation): Register variables with cgraph.
	* cgraphunit.c (cgraph_finalize_compilation_unit): Use finish_aliases_1.        * toplev.c (compile_file): Use finish_aliases_2 instead of
	process_pending_assemble_output_defs.
	* tree.h (finish_aliases_1, finish_aliases_2): Declare.
	(process_pending_assemble_output_defs): Remove.
	
	* gcc.c-torture/compile/20040323-1.c: Don't xfail for solaris.
	(_rtld_global): New.
	* gcc.dg/weak/weak-3.c (ffoox1f, ffoox1g): Define.
	* gcc.dg/weak/weak-9.c (notf1, notf2, notf3, notf4): Define.
	
	* gcc.dg/alias-3.c: New.
	* gcc.dg/alias-4.c: New.
	* gcc.dg/alias-5.c: New.
	* gcc.dg/alias-6.c: New.

Patches:
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/ChangeLog.diff?cvsroot=gcc&r1=2.7874&r2=2.7875
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cgraphunit.c.diff?cvsroot=gcc&r1=1.94&r2=1.95
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/passes.c.diff?cvsroot=gcc&r1=2.73&r2=2.74
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/toplev.c.diff?cvsroot=gcc&r1=1.946&r2=1.947
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/tree.h.diff?cvsroot=gcc&r1=1.702&r2=1.703
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/varasm.c.diff?cvsroot=gcc&r1=1.481&r2=1.482
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/ChangeLog.diff?cvsroot=gcc&r1=1.5174&r2=1.5175
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/gcc.c-torture/compile/20040323-1.c.diff?cvsroot=gcc&r1=1.3&r2=1.4
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/gcc.dg/alias-3.c.diff?cvsroot=gcc&r1=NONE&r2=1.1
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/gcc.dg/alias-4.c.diff?cvsroot=gcc&r1=NONE&r2=1.1
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/gcc.dg/alias-5.c.diff?cvsroot=gcc&r1=NONE&r2=1.1
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/gcc.dg/alias-6.c.diff?cvsroot=gcc&r1=NONE&r2=1.1
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/gcc.dg/weak/weak-3.c.diff?cvsroot=gcc&r1=1.5&r2=1.6
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/gcc.dg/weak/weak-9.c.diff?cvsroot=gcc&r1=1.3&r2=1.4

Comment 19 GCC Commits 2005-03-16 20:36:58 UTC
Subject: Bug 15700

CVSROOT:	/cvs/gcc
Module name:	gcc
Branch: 	gcc-4_0-branch
Changes by:	rth@gcc.gnu.org	2005-03-16 20:36:45

Modified files:
	gcc            : ChangeLog cgraphunit.c passes.c toplev.c tree.h 
	                 varasm.c 
	gcc/testsuite  : ChangeLog 
	gcc/testsuite/gcc.c-torture/compile: 20040323-1.c 
	gcc/testsuite/gcc.dg/weak: weak-3.c weak-9.c 
Added files:
	gcc/testsuite/gcc.dg: alias-3.c alias-4.c alias-5.c alias-6.c 

Log message:
	PR middle-end/15700
	* varasm.c (struct alias_pair): Rename from struct output_def_pair.
	(alias_pairs): Rename from output_defs.
	(find_decl_and_mark_needed): Split out from assemble_alias.
	(do_assemble_alias): New.
	(assemble_output_def): Remove.
	(finish_aliases_1, finish_aliases_2): New.
	(process_pending_assemble_output_defs): Remove.
	(assemble_alias): Defer aliases for which we don't yet have a
	non-external decl for the target symbol.
	* passes.c (rest_of_decl_compilation): Register variables with cgraph.
	* cgraphunit.c (cgraph_finalize_compilation_unit): Use finish_aliases_1.        * toplev.c (compile_file): Use finish_aliases_2 instead of
	process_pending_assemble_output_defs.
	* tree.h (finish_aliases_1, finish_aliases_2): Declare.
	(process_pending_assemble_output_defs): Remove.
	
	* gcc.c-torture/compile/20040323-1.c: Don't xfail for solaris.
	(_rtld_global): New.
	* gcc.dg/weak/weak-3.c (ffoox1f, ffoox1g): Define.
	* gcc.dg/weak/weak-9.c (notf1, notf2, notf3, notf4): Define.
	
	* gcc.dg/alias-3.c: New.
	* gcc.dg/alias-4.c: New.
	* gcc.dg/alias-5.c: New.
	* gcc.dg/alias-6.c: New.

Patches:
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/ChangeLog.diff?cvsroot=gcc&only_with_tag=gcc-4_0-branch&r1=2.7592.2.56&r2=2.7592.2.57
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cgraphunit.c.diff?cvsroot=gcc&only_with_tag=gcc-4_0-branch&r1=1.93.2.1&r2=1.93.2.2
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/passes.c.diff?cvsroot=gcc&only_with_tag=gcc-4_0-branch&r1=2.72&r2=2.72.2.1
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/toplev.c.diff?cvsroot=gcc&only_with_tag=gcc-4_0-branch&r1=1.944&r2=1.944.2.1
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/tree.h.diff?cvsroot=gcc&only_with_tag=gcc-4_0-branch&r1=1.693&r2=1.693.2.1
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/varasm.c.diff?cvsroot=gcc&only_with_tag=gcc-4_0-branch&r1=1.477.6.1&r2=1.477.6.2
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.50&r2=1.5084.2.51
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/gcc.c-torture/compile/20040323-1.c.diff?cvsroot=gcc&only_with_tag=gcc-4_0-branch&r1=1.3&r2=1.3.40.1
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/gcc.dg/alias-3.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/gcc.dg/alias-4.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/gcc.dg/alias-5.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/gcc.dg/alias-6.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/gcc.dg/weak/weak-3.c.diff?cvsroot=gcc&only_with_tag=gcc-4_0-branch&r1=1.5&r2=1.5.18.1
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/gcc.dg/weak/weak-9.c.diff?cvsroot=gcc&only_with_tag=gcc-4_0-branch&r1=1.3&r2=1.3.18.1

Comment 20 Richard Henderson 2005-03-16 20:39:00 UTC
Fixed.
Comment 21 Richard Henderson 2005-03-16 21:51:36 UTC
*** Bug 20167 has been marked as a duplicate of this bug. ***
Comment 22 GCC Commits 2005-03-31 13:02:59 UTC
Subject: Bug 15700

CVSROOT:	/cvs/gcc
Module name:	gcc
Changes by:	amylaar@gcc.gnu.org	2005-03-31 13:02:37

Modified files:
	gcc/testsuite/gcc.c-torture/compile: 20011119-1.c 20011119-2.c 

Log message:
	Fix fallout from PR middle-end/15700:
	* gcc.c-torture/compile/20011119-1.c: Take
	__USER_LABEL_PREFIX__ into account.
	* gcc.c-torture/compile/20011119-2.c: Likewise.

Patches:
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/gcc.c-torture/compile/20011119-1.c.diff?cvsroot=gcc&r1=1.2&r2=1.3
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/gcc.c-torture/compile/20011119-2.c.diff?cvsroot=gcc&r1=1.2&r2=1.3

Comment 23 GCC Commits 2005-04-01 11:39:05 UTC
Subject: Bug 15700

CVSROOT:	/cvs/gcc
Module name:	gcc
Changes by:	amylaar@gcc.gnu.org	2005-04-01 11:38:53

Modified files:
	gcc/testsuite  : ChangeLog 

Log message:
	Add missing entry from yesterday:
	2005-03-31  J"orn Rennecke <joern.rennecke@st.com>
	
	Fix fallout from PR middle-end/15700:
	* gcc.c-torture/compile/20011119-1.c: Take
	__USER_LABEL_PREFIX__ into account.
	* gcc.c-torture/compile/20011119-2.c: Likewise.

Patches:
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/ChangeLog.diff?cvsroot=gcc&r1=1.5259&r2=1.5260