The program below will crash when run with a segmentation fault. Compiling with the command line g++ -O3 -Wall main.cc produced the following incorrect warning which might help locate the problem. main.cc:5 warning: 'int v' might be uninitialized in this function --------------------------------------------------------------- template<int b> class o { public: template<typename T> static void do_add(T* p, T v); }; template<> template<typename T> inline void o<32>::do_add(T* p, T v) { *p += v; } template<typename T> inline void add(T* p, T v) { o<32>::do_add<T>(p, v); } int main() { int a = 0x1000; add(&a, 0x2000); return a; } --------------------------------------------------------------- Environment: cygwin on Windows XP Release: gcc version 3.2 20020927 (prerelease)
Confirmed. Crashes from 3.0 to present mainline. Optimization flags are irrelevant. There's some stack corruption going on, since it crashes here: (gdb) bt #0 0x08048526 in void o<32>::do_add<int>(int*, int) (this=0xbffff178, p=0x2000, v=-1073745540) at x.cc:12 #1 0x08048518 in add<int> (p=0xbffff178, v=8192) at x.cc:18 #2 0x080484ca in main () at x.cc:24 #3 0x4012a9ed in __libc_start_main () from /lib/libc.so.6 Note that in do_add, p=0x2000 and v=invalid, whereas we really should have p be a reasonable pointer and v having the value 0x2000! W.
Forgot to say this: with 2.95, the parser has a problem with understanding the explicit specialization. Making it a general template, the code doesn't crash. So I'd say it's a regression, though it's hard to judge here. (Then let's say that an invalid error message is less bad than a miscompilation, and then it's a regression :-) W.
Since my analysis has not come through yet, I will post them both again but this time use the web page instead of email. First email sent: This still happens on the mainline on powerpc-apple-darwin (but does not seg fault for a different reason): _main: LFB7: li r4,8192 li r3,4096 lwz r5,0(r4) add r2,r5,r9 stw r2,0(r4) blr It also happens on the tree-ssa branch, since that branch has tree dumping after inlining takes place: ;; Function int main() (main) int main() () { int * a.2; { { int a; a = 4096; a.2 = &a; { int v; int * p; p = a.2; v = 8192; { { { int v; int * p; struct o<32> * const this; <--- where the f*** did this come from and why, since do_add is static. this = (struct o<32> * const)p; p = (int *)v; { int T.1; { T.1 = *p; *p = T.1 + v } } } } } }; return a; } }; return 0; } second email sent replying to what Wolfgang Bangerth wrote: Not it is not because of stack corruption, it is because gcc is adding a variable called this to the `static' class function. On Thursday, May 22, 2003, at 14:34 US/Eastern, bangerth@dealii.org wrote: > 0x08048526 in void o<32>::do_add<int>(int*, int) (this=0xbffff178, > p=0x2000, v=-1073745540) at x.cc:12
Problem propagating 'static' from primary template to specialization.
Fixed in 3.3 branch and main trunk.