Bug 188773 - inline optimization appears broken
Summary: inline optimization appears broken
Keywords:
Status: CLOSED NOTABUG
Alias: None
Product: Fedora
Classification: Fedora
Component: gcc4
Version: 5
Hardware: i386
OS: Linux
medium
medium
Target Milestone: ---
Assignee: Jakub Jelinek
QA Contact:
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2006-04-13 01:13 UTC by Steven Dake
Modified: 2016-04-26 18:17 UTC (History)
0 users

Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Clone Of:
Environment:
Last Closed: 2006-04-13 09:48:34 UTC
Type: ---
Embargoed:


Attachments (Terms of Use)
trunk tarball of openais source code (372.48 KB, application/octet-stream)
2006-04-13 01:13 UTC, Steven Dake
no flags Details
patch to workaround the problem in the optimizer (492 bytes, patch)
2006-04-13 01:22 UTC, Steven Dake
no flags Details | Diff

Description Steven Dake 2006-04-13 01:13:36 UTC
Description of problem:
I have an application that I develop that has 3 levels of inlines.  If I compile
with -O2 the app crashes, with -O1 the app doesn't crash.  The app also works
with gcc 4.0, gcc 3.4.5, gcc 3.2.2, etc.

Version-Release number of selected component (if applicable):
[sdake@clever ~]$ gcc --version
gcc (GCC) 4.1.0 20060304 (Red Hat 4.1.0-3)
Copyright (C) 2006 Free Software Foundation, Inc.
T

How reproducible:
100%

Steps to Reproduce:
1. untar attached openais-trunk.tar.gz and cd into openais-trunk directory
2. run make in top level directory
3. cd lcr
4. type ./test
  
Actual results:
program segfaults.  It appears data is corrupted around the lcr_comp_find
function which inlines several other functions.  If I specify a "noinline"
attribute to the functoin the code works.  See attachment.

Expected results:
[root@shih lcr]# ./test
UIS server thread started 4
A - version 0 constructor context 0xaaaa0000
B - version 0 constructor context 0xbbbb0000
A - version 1 constructor context 0xaaaa1111
B - version 1 constructor context 0xbbbb1111
A - version 0 func1
A - version 0 func2
A - version 0 func3
A - version 1 func1
A - version 1 func2
A - version 1 func3
B - version 0 func1
B - version 0 func2
B - version 0 func3
B - version 1 func1
B - version 1 func2
B - version 1 func3



Additional info:
attached trunk version of openais
attached patch which works around apparent optimizer bug in gcc

Comment 1 Steven Dake 2006-04-13 01:13:37 UTC
Created attachment 127684 [details]
trunk tarball of openais source code

Comment 2 Steven Dake 2006-04-13 01:22:41 UTC
Created attachment 127685 [details]
patch to workaround the problem in the optimizer

patch that works around the problem  also putting printfs in the lcr_comp_find
functions seems to fix it

Comment 3 Jakub Jelinek 2006-04-13 09:48:34 UTC
The source is buggy, violates strict aliasing (and additionally by additional
cast clearly just makes a GCC warning go away rather than fixing a bug in it).
See info gcc, search for -fstrict-aliasing or better yet the ISO C99 standard.
After fixing it the program no longer segfaults:
--- lcr/lcr_ifact.c.jj  2006-03-24 09:28:12.000000000 +0100
+++ lcr/lcr_ifact.c     2006-04-13 11:51:00.000000000 +0200
@@ -88,7 +88,10 @@ static inline struct lcr_component_insta
        unsigned int version,
        int *iface_number)
 {
-       struct lcr_component_instance *instance;
+       union {
+               struct lcr_component_instance *instance;
+               void *ptr;
+       } u;
        unsigned int component_handle = 0;
        int i;

@@ -97,14 +100,14 @@ static inline struct lcr_component_insta
         */
        hdb_iterator_reset (&lcr_component_instance_database);
        while (hdb_iterator_next (&lcr_component_instance_database,
-               (void **)(void *)&instance, &component_handle) == 0) {
+               &u.ptr, &component_handle) == 0) {

-               for (i = 0; i < instance->iface_count; i++) {
-                       if ((strcmp (instance->ifaces[i].name, iface_name) == 0)
&&
-                               instance->ifaces[i].version == version) {
+               for (i = 0; i < u.instance->iface_count; i++) {
+                       if ((strcmp (u.instance->ifaces[i].name, iface_name) ==
0) &&
+                               u.instance->ifaces[i].version == version) {

                                *iface_number = i;
-                               return (instance);
+                               return (u.instance);
                        }
                }
                hdb_handle_put (&lcr_component_instance_database,
component_handle);
@@ -116,7 +119,10 @@ static inline struct lcr_component_insta
 static inline int lcr_lib_loaded (
        char *library_name)
 {
-       struct lcr_component_instance *instance;
+       union {
+               struct lcr_component_instance *instance;
+               void *ptr;
+       } u;
        unsigned int component_handle = 0;

        /*
@@ -124,9 +130,9 @@ static inline int lcr_lib_loaded (
         */
        hdb_iterator_reset (&lcr_component_instance_database);
        while (hdb_iterator_next (&lcr_component_instance_database,
-               (void **)(void *)&instance, &component_handle) == 0) {
+               &u.ptr, &component_handle) == 0) {

-               if (strcmp (instance->library_name, library_name) == 0) {
+               if (strcmp (u.instance->library_name, library_name) == 0) {
                        return (1);
                }



Comment 4 Steven Dake 2006-04-13 17:32:43 UTC
Thanks Jakub for the info about strict aliasing and the bugfix.  Unfortunately I
think we use this type of thing alot so there will be many more code changes. 
Thanks again for the pointer.

Regards
-steve


Note You need to log in before you can comment on or make changes to this bug.