https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69236
Bug ID: 69236 Summary: Wrong function call when use weak statement Product: gcc Version: 4.8.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: thln47 at free dot fr Target Milestone: --- Wrong function call when use weak statement Hello, Host : PC mingw32 Target : PC mingw32 I have a problem when I use weak statement with two functions. The compiler keep the address of the first function for all of following. So the problem occurs even I compile module1.c alone or with module2. I try to change the optimization flags but I have the same result. When I use another gcc version (GCC 4.9.3 for Cywin64) it's works. Thanks for reply. ------------------------------------------------------------------------------------ Here is output : ------------------------------------------------------------------------------------ WEAK BUG Checker Compiler version : 4.8.1! function_Get_F1 = 004016B0 function_Get_F2 = 004016B0 ..\src\module1.c : Get_F1 ..\src\module1.c : Get_F1 BUG (test=1) ------------------------------------------------------------------------------------ Here is my code for module1.c ------------------------------------------------------------------------------------ /* * module1.c * * Created on: Jan 11, 2016 * Author: Thierry */ #include <stdio.h> #include <stdint.h> //#define __WEAK #define __WEAK __attribute__((weak)) extern uint16_t Get_F1(void); extern uint16_t Get_F2(uint16_t param_index); __WEAK uint16_t Get_F1(void) { printf("%s : %s\n", __FILE__, __FUNCTION__); return 1; } __WEAK uint16_t Get_F2(uint16_t param_index) { printf("%s : %s\n", __FILE__, __FUNCTION__); return 1+param_index; } void bug_highlight(void) { uint16_t (* function_Get_F1)(void); uint16_t (* function_Get_F2)(uint16_t param_index); function_Get_F1 = &Get_F1; function_Get_F2 = &Get_F2; printf("function_Get_F1 = %p\n", function_Get_F1); printf("function_Get_F2 = %p\n", function_Get_F2); uint16_t test; test = Get_F1(); test = Get_F2(test); if (test==2) { printf("test Ok with module1\n"); } else if (test==20) { printf("test Ok with module2\n"); } else { printf("BUG (test=%d)\n", test); } } int main(void){ setbuf(stdout, NULL); printf("WEAK BUG Checker Compiler version : %s!\n", __VERSION__); bug_highlight(); return 0; } ------------------------------------------------------------------------------------ Here is my code for module2.c ------------------------------------------------------------------------------------ /* * module2.c * * Created on: Jan 11, 2016 * Author: Thierry */ #include <stdio.h> #include <stdint.h> uint16_t Get_F1(void) { printf("%s : %s\n", __FILE__, __FUNCTION__); return 10; } uint16_t Get_F2(uint16_t param_index) { printf("%s : %s\n", __FILE__, __FUNCTION__); return 10+param_index; } ------------------------------------------------------------------------------------ Here is compiler command line ------------------------------------------------------------------------------------ gcc -O0 -g3 -Wall -c -fmessage-length=0 -Wextra -v -o src\module1.o ..\src\module1.c Using built-in specs. COLLECT_GCC=D:\Atollic\TrueSTUDIO for ARM 5.4.0\PCTools\bin\gcc.exe Target: mingw32 Configured with: ../gcc-4.8.1/configure --prefix=/mingw --host=mingw32 --build=mingw32 --without-pic --enable-shared --enable-static --with-gnu-ld --enable-lto --enable-libssp --disable-multilib --enable-languages=c,c++,fortran,objc,obj-c++,ada --disable-sjlj-exceptions --with-dwarf2 --disable-win32-registry --enable-libstdcxx-debug --enable-version-specific-runtime-libs --with-gmp=/usr/src/pkg/gmp-5.1.2-1-mingw32-src/bld --with-mpc=/usr/src/pkg/mpc-1.0.1-1-mingw32-src/bld --with-mpfr= --with-system-zlib --with-gnu-as --enable-decimal-float=yes --enable-libgomp --enable-threads --with-libiconv-prefix=/mingw32 --with-libintl-prefix=/mingw --disable-bootstrap LDFLAGS=-s CFLAGS=-D_USE_32BIT_TIME_T Thread model: win32 gcc version 4.8.1 (GCC) COLLECT_GCC_OPTIONS='-O0' '-g3' '-Wall' '-c' '-fmessage-length=0' '-Wextra' '-v' '-o' 'src\module1.o' '-mtune=generic' '-march=pentiumpro' d:/atollic/truestudio for arm 5.4.0/pctools/bin/../libexec/gcc/mingw32/4.8.1/cc1.exe -quiet -v -iprefix d:\atollic\truestudio for arm 5.4.0\pctools\bin\../lib/gcc/mingw32/4.8.1/ -dD ..\src\module1.c -quiet -dumpbase module1.c -mtune=generic -march=pentiumpro -auxbase-strip src\module1.o -g3 -O0 -Wall -Wextra -version -fmessage-length=0 -o C:\Users\Thierry\AppData\Local\Temp\cc1BmIoz.s GNU C (GCC) version 4.8.1 (mingw32) compiled by GNU C version 4.8.1, GMP version 5.1.2, MPFR version 3.1.2, MPC version 1.0.1 GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072 ignoring duplicate directory "d:/atollic/truestudio for arm 5.4.0/pctools/lib/gcc/../../lib/gcc/mingw32/4.8.1/include" ignoring duplicate directory "d:/atollic/truestudio for arm 5.4.0/pctools/lib/gcc/../../lib/gcc/mingw32/4.8.1/../../../../include" ignoring nonexistent directory "/mingw/include" ignoring duplicate directory "d:/atollic/truestudio for arm 5.4.0/pctools/lib/gcc/../../lib/gcc/mingw32/4.8.1/include-fixed" ignoring duplicate directory "d:/atollic/truestudio for arm 5.4.0/pctools/lib/gcc/../../lib/gcc/mingw32/4.8.1/../../../../mingw32/include" ignoring nonexistent directory "/mingw/include" #include "..." search starts here: #include <...> search starts here: d:\atollic\truestudio for arm 5.4.0\pctools\bin\../lib/gcc/mingw32/4.8.1/include d:\atollic\truestudio for arm 5.4.0\pctools\bin\../lib/gcc/mingw32/4.8.1/../../../../include d:\atollic\truestudio for arm 5.4.0\pctools\bin\../lib/gcc/mingw32/4.8.1/include-fixed d:\atollic\truestudio for arm 5.4.0\pctools\bin\../lib/gcc/mingw32/4.8.1/../../../../mingw32/include End of search list. GNU C (GCC) version 4.8.1 (mingw32) compiled by GNU C version 4.8.1, GMP version 5.1.2, MPFR version 3.1.2, MPC version 1.0.1 GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072 Compiler executable checksum: 767202a405449496e68a54c4eee91a28 COLLECT_GCC_OPTIONS='-O0' '-g3' '-Wall' '-c' '-fmessage-length=0' '-Wextra' '-v' '-o' 'src\module1.o' '-mtune=generic' '-march=pentiumpro' d:/atollic/truestudio for arm 5.4.0/pctools/bin/../lib/gcc/mingw32/4.8.1/../../../../mingw32/bin/as.exe -v -o src\module1.o C:\Users\Thierry\AppData\Local\Temp\cc1BmIoz.s GNU assembler version 2.23.2 (mingw32) using BFD version (GNU Binutils) 2.23.2 COMPILER_PATH=d:/atollic/truestudio for arm 5.4.0/pctools/bin/../libexec/gcc/mingw32/4.8.1/;d:/atollic/truestudio for arm 5.4.0/pctools/bin/../libexec/gcc/;d:/atollic/truestudio for arm 5.4.0/pctools/bin/../lib/gcc/mingw32/4.8.1/../../../../mingw32/bin/ LIBRARY_PATH=d:/atollic/truestudio for arm 5.4.0/pctools/bin/../lib/gcc/mingw32/4.8.1/;d:/atollic/truestudio for arm 5.4.0/pctools/bin/../lib/gcc/;d:/atollic/truestudio for arm 5.4.0/pctools/bin/../lib/gcc/mingw32/4.8.1/../../../../mingw32/lib/;d:/atollic/truestudio for arm 5.4.0/pctools/bin/../lib/gcc/mingw32/4.8.1/../../../ COLLECT_GCC_OPTIONS='-O0' '-g3' '-Wall' '-c' '-fmessage-length=0' '-Wextra' '-v' '-o' 'src\module1.o' '-mtune=generic' '-march=pentiumpro' gcc -o weak_bug.exe src\module1.o ------------------------------------------------------------------------------------ Here is disassemby of bug_highlight function ------------------------------------------------------------------------------------ 29 void bug_highlight(void) { bug_highlight: 0040170b: push %ebp 0040170c: mov %esp,%ebp 0040170e: sub $0x28,%esp 34 function_Get_F1 = &Get_F1; 00401711: movl $0x4016b0,-0xc(%ebp) 35 function_Get_F2 = &Get_F2; 00401718: movl $0x4016b0,-0x10(%ebp) 37 printf("function_Get_F1 = %p\n", function_Get_F1); 0040171f: mov -0xc(%ebp),%eax 00401722: mov %eax,0x4(%esp) 00401726: movl $0x40507e,(%esp) 0040172d: call 0x403778 <printf> 38 printf("function_Get_F2 = %p\n", function_Get_F2); 00401732: mov -0x10(%ebp),%eax 00401735: mov %eax,0x4(%esp) 00401739: movl $0x405094,(%esp) 00401740: call 0x403778 <printf> 42 test = Get_F1(); 00401745: call 0x4016b0 <Get_F1> 0040174a: mov %ax,-0x12(%ebp) 43 test = Get_F2(test); 0040174e: movzwl -0x12(%ebp),%eax 00401752: mov %eax,(%esp) 00401755: call 0x4016b0 <Get_F1> 0040175a: mov %ax,-0x12(%ebp) 45 if (test==2) { 0040175e: cmpw $0x2,-0x12(%ebp) 00401763: jne 0x401773 <bug_highlight+104> 46 printf("test Ok with module1\n"); 00401765: movl $0x4050aa,(%esp) 0040176c: call 0x403780 <puts> 00401771: jmp 0x40179c <bug_highlight+145> 47 } else if (test==20) { 00401773: cmpw $0x14,-0x12(%ebp) 00401778: jne 0x401788 <bug_highlight+125> 48 printf("test Ok with module2\n"); 0040177a: movl $0x4050bf,(%esp) 00401781: call 0x403780 <puts> 00401786: jmp 0x40179c <bug_highlight+145> 50 printf("BUG (test=%d)\n", test); 00401788: movzwl -0x12(%ebp),%eax 0040178c: mov %eax,0x4(%esp) 00401790: movl $0x4050d4,(%esp) 00401797: call 0x403778 <printf> 52 } 0040179c: leave 0040179d: ret