public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c/31236]  New: incorrect output on external symbol address cast as integer used in conditional statement
@ 2007-03-16 23:07 sh-list at ssc-studios dot com
  2007-03-16 23:09 ` [Bug c/31236] " pinskia at gcc dot gnu dot org
                   ` (5 more replies)
  0 siblings, 6 replies; 7+ messages in thread
From: sh-list at ssc-studios dot com @ 2007-03-16 23:07 UTC (permalink / raw)
  To: gcc-bugs

/*
when using an external function pointer cast as an interrupt in a if (&function
== 0) statement the compiler assume the pointer is non-null and optimize out
the if right away even tho the symbol could indeed be null and optimizations
are disabled.

this is a big problem when values are set as symbol addresses in the linker
script.

gcc and g++ give the same result
.cpp and .c extentions give the same result
all targets I've tested (i386, arm, powerpc) give the same result

Linux shockenhull 2.6.16.13-4-smp #1 SMP Wed May 3 04:53:23 UTC 2006 i686
athlon i386 GNU/Linux

GCC versions I tried:
i686-pc-linux-gnu-gcc (GCC) 4.1.2
gcc (GCC) 4.1.0 (SUSE Linux)
arm-unknown-elf-gcc (GCC) 4.1.1
ppc-unknown-elf-gcc (GCC) 4.1.1
i386-unknown-elf-gcc (GCC) 4.1.1
*/
//------------if-bug-function-pointers.cpp-----------

extern void SomeLinkerScriptDefinedSymbol(void);

#define SOMEVALUE ((int)&SomeLinkerScriptDefinedSymbol)

int main()
{
#ifdef USETEMP
        // this works fine
        int i = SOMEVALUE;
        if(i == 0){
                return 0;
        } else {
                return -1;
        }
#else
        // this incorrectly assumes SOMEVALUE != 0
        if(SOMEVALUE == 0){
                return 0;
        } else {
                return -1;
        }
#endif
}

//----------------------------------------
/*
shockenhull@shockenhull:~/tmp> i686-pc-linux-gnu-gcc -v -save-temps -O0 -c
if-bug-function-pointers.c -o if-bug-function-pointers.o
Using built-in specs.
Target: i686-pc-linux-gnu
Configured with: ../configure --prefix=/home/shockenhull/bin/gcc-4.1.2
Thread model: posix
gcc version 4.1.2
 /home/shockenhull/bin/gcc-4.1.2/libexec/gcc/i686-pc-linux-gnu/4.1.2/cc1 -E
-quiet -v if-bug-function-pointers.c -mtune=pentiumpro -O0 -fpch-preprocess -o
if-bug-function-pointers.i
ignoring nonexistent directory
"/home/shockenhull/bin/gcc-4.1.2/lib/gcc/i686-pc-linux-gnu/4.1.2/../../../../i686-pc-linux-gnu/include"
#include "..." search starts here:
#include <...> search starts here:
 /usr/local/include
 /home/shockenhull/bin/gcc-4.1.2/include
 /home/shockenhull/bin/gcc-4.1.2/lib/gcc/i686-pc-linux-gnu/4.1.2/include
 /usr/include
End of search list.
 /home/shockenhull/bin/gcc-4.1.2/libexec/gcc/i686-pc-linux-gnu/4.1.2/cc1
-fpreprocessed if-bug-function-pointers.i -quiet -dumpbase
if-bug-function-pointers.c -mtune=pentiumpro -auxbase-strip
if-bug-function-pointers.o -O0 -version -o if-bug-function-pointers.s
GNU C version 4.1.2 (i686-pc-linux-gnu)
        compiled by GNU C version 4.1.0 (SUSE Linux).
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
Compiler executable checksum: ee7023030d57847fe562209522d89579
 as -V -Qy -o if-bug-function-pointers.o if-bug-function-pointers.s
GNU assembler version 2.16.91.0.5 (i586-suse-linux) using BFD version
2.16.91.0.5 20051219 (SUSE Linux)
shockenhull@shockenhull:~/tmp>      
----------------------------------------
*/


-- 
           Summary: incorrect output on external symbol address cast as
                    integer used in conditional statement
           Product: gcc
           Version: 4.1.2
            Status: UNCONFIRMED
          Severity: major
          Priority: P3
         Component: c
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: sh-list at ssc-studios dot com
 GCC build triplet: i686-pc-linux-gnu
  GCC host triplet: i686-pc-linux-gnu
GCC target triplet: any


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=31236


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [Bug c/31236] incorrect output on external symbol address cast as integer used in conditional statement
  2007-03-16 23:07 [Bug c/31236] New: incorrect output on external symbol address cast as integer used in conditional statement sh-list at ssc-studios dot com
@ 2007-03-16 23:09 ` pinskia at gcc dot gnu dot org
  2007-03-17  0:07 ` sh-list at ssc-studios dot com
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: pinskia at gcc dot gnu dot org @ 2007-03-16 23:09 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #1 from pinskia at gcc dot gnu dot org  2007-03-16 23:08 -------
You need to mark the function as weak not to assume the function is non-null.


-- 

pinskia at gcc dot gnu dot org changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |RESOLVED
         Resolution|                            |INVALID


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=31236


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [Bug c/31236] incorrect output on external symbol address cast as integer used in conditional statement
  2007-03-16 23:07 [Bug c/31236] New: incorrect output on external symbol address cast as integer used in conditional statement sh-list at ssc-studios dot com
  2007-03-16 23:09 ` [Bug c/31236] " pinskia at gcc dot gnu dot org
@ 2007-03-17  0:07 ` sh-list at ssc-studios dot com
  2007-03-17  0:20 ` pinskia at gcc dot gnu dot org
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: sh-list at ssc-studios dot com @ 2007-03-17  0:07 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #2 from sh-list at ssc-studios dot com  2007-03-17 00:07 -------
I don't think this behavior is part of the C or C++ standard.
nor is __attribute__ (( weak ))
this behavior of gcc seems to be undocumented.

I don't see how usefull it is to have gcc assume pointers to functions to be
non-null in conditionals as when a programmer checks for the pointer to be null
or not in a conditional statement that should hint the compiler as it might be
null (unless the function is within this translation unit).

proposed fix: extern should cause the compiler to assume NOTHING about the
location of the symbol by default.

other reason for bug: embedded systems can have symbols legally starting at
address 0, including a function (the reset interrupt handler for example)


-- 

sh-list at ssc-studios dot com changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|RESOLVED                    |UNCONFIRMED
         Resolution|INVALID                     |


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=31236


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [Bug c/31236] incorrect output on external symbol address cast as integer used in conditional statement
  2007-03-16 23:07 [Bug c/31236] New: incorrect output on external symbol address cast as integer used in conditional statement sh-list at ssc-studios dot com
  2007-03-16 23:09 ` [Bug c/31236] " pinskia at gcc dot gnu dot org
  2007-03-17  0:07 ` sh-list at ssc-studios dot com
@ 2007-03-17  0:20 ` pinskia at gcc dot gnu dot org
  2007-03-17 17:31 ` sh-list at ssc-studios dot com
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: pinskia at gcc dot gnu dot org @ 2007-03-17  0:20 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #3 from pinskia at gcc dot gnu dot org  2007-03-17 00:19 -------
Still invalid, the C standard talks about NULL as being at the location 0 so it
is basically it is invalid for a function to be located at 0/NULL.

Again if you want a function to be possibly located at NULL/0, use weak.

Also why should we document all value optimizations.


-- 

pinskia at gcc dot gnu dot org changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |RESOLVED
         Resolution|                            |INVALID


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=31236


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [Bug c/31236] incorrect output on external symbol address cast as integer used in conditional statement
  2007-03-16 23:07 [Bug c/31236] New: incorrect output on external symbol address cast as integer used in conditional statement sh-list at ssc-studios dot com
                   ` (2 preceding siblings ...)
  2007-03-17  0:20 ` pinskia at gcc dot gnu dot org
@ 2007-03-17 17:31 ` sh-list at ssc-studios dot com
  2007-03-17 17:47 ` pinskia at gcc dot gnu dot org
  2007-03-21  4:00 ` bangerth at dealii dot org
  5 siblings, 0 replies; 7+ messages in thread
From: sh-list at ssc-studios dot com @ 2007-03-17 17:31 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #4 from sh-list at ssc-studios dot com  2007-03-17 17:31 -------
so in other words you're saying the solution to this is 
"if you want it to work with GCC, make your code non-portable"

afaik "__attribute__ (( weak ))" is not part of the standard, its not a
portable solution.

the fact that
        #define SOMEVALUE ((int)&SomeLinkerScriptDefinedSymbol)
        int i = SOMEVALUE; 
        if(i == 0){
and
        if(SOMEVALUE == 0){

give a different result makes gcc act inconsistently on code that should be
equivalent.

what are the real-life speed and size gains of this optimization?


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=31236


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [Bug c/31236] incorrect output on external symbol address cast as integer used in conditional statement
  2007-03-16 23:07 [Bug c/31236] New: incorrect output on external symbol address cast as integer used in conditional statement sh-list at ssc-studios dot com
                   ` (3 preceding siblings ...)
  2007-03-17 17:31 ` sh-list at ssc-studios dot com
@ 2007-03-17 17:47 ` pinskia at gcc dot gnu dot org
  2007-03-21  4:00 ` bangerth at dealii dot org
  5 siblings, 0 replies; 7+ messages in thread
From: pinskia at gcc dot gnu dot org @ 2007-03-17 17:47 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #5 from pinskia at gcc dot gnu dot org  2007-03-17 17:47 -------
Well linker scripts are already non portable and not mentioned in the standard
and you are violating the C/C++ standards if the address of a variable is NULL
(0) :).

Also -O2 with -DUSETEMP gives the same results as without it so it is not
inconsistent, even the code is equalivant, the code is not the same when it
comes to without optimization :).


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=31236


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [Bug c/31236] incorrect output on external symbol address cast as integer used in conditional statement
  2007-03-16 23:07 [Bug c/31236] New: incorrect output on external symbol address cast as integer used in conditional statement sh-list at ssc-studios dot com
                   ` (4 preceding siblings ...)
  2007-03-17 17:47 ` pinskia at gcc dot gnu dot org
@ 2007-03-21  4:00 ` bangerth at dealii dot org
  5 siblings, 0 replies; 7+ messages in thread
From: bangerth at dealii dot org @ 2007-03-21  4:00 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #6 from bangerth at dealii dot org  2007-03-21 03:59 -------
(In reply to comment #4)
> so in other words you're saying the solution to this is 
> "if you want it to work with GCC, make your code non-portable"
> 
> afaik "__attribute__ (( weak ))" is not part of the standard, its not a
> portable solution.
> 
> the fact that
>         #define SOMEVALUE ((int)&SomeLinkerScriptDefinedSymbol)
>         int i = SOMEVALUE; 
>         if(i == 0){
> and
>         if(SOMEVALUE == 0){
> 
> give a different result makes gcc act inconsistently on code that should be
> equivalent.

I would argue that it is a missed optimization that it doesn't optimize
away both cases.

That said, a compiler is entirely within the standard to assume that the
address of a symbol is non-null. That's simply the case in a well-formed
program. If you specifically want something different, then you need to
let the compiler know this.

As a second point, you are surely aware of the fact that casting a
pointer (in general) to int is not portable, and a function pointer in
particular (since function pointers may not be represented as pointers,
but potentially as structures). The latter is where the difference in
optimization comes from.

W.


-- 

bangerth at dealii dot org changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |bangerth at dealii dot org


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=31236


^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2007-03-21  4:00 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-03-16 23:07 [Bug c/31236] New: incorrect output on external symbol address cast as integer used in conditional statement sh-list at ssc-studios dot com
2007-03-16 23:09 ` [Bug c/31236] " pinskia at gcc dot gnu dot org
2007-03-17  0:07 ` sh-list at ssc-studios dot com
2007-03-17  0:20 ` pinskia at gcc dot gnu dot org
2007-03-17 17:31 ` sh-list at ssc-studios dot com
2007-03-17 17:47 ` pinskia at gcc dot gnu dot org
2007-03-21  4:00 ` bangerth at dealii dot org

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).