Bug 188773 - inline optimization appears broken
inline optimization appears broken
Status: CLOSED NOTABUG
Product: Fedora
Classification: Fedora
Component: gcc4 (Show other bugs)
5
i386 Linux
medium Severity medium
: ---
: ---
Assigned To: Jakub Jelinek
:
Depends On:
Blocks:
  Show dependency treegraph
 
Reported: 2006-04-12 21:13 EDT by Steven Dake
Modified: 2016-04-26 14:17 EDT (History)
0 users

See Also:
Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
Environment:
Last Closed: 2006-04-13 05:48:34 EDT
Type: ---
Regression: ---
Mount Type: ---
Documentation: ---
CRM:
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---


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

  None (edit)
Description Steven Dake 2006-04-12 21:13:36 EDT
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-12 21:13:37 EDT
Created attachment 127684 [details]
trunk tarball of openais source code
Comment 2 Steven Dake 2006-04-12 21:22:41 EDT
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 05:48:34 EDT
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 13:32:43 EDT
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.