From mboxrd@z Thu Jan 1 00:00:00 1970 From: Robert Lipe To: Jason Merrill Cc: egcs@cygnus.com Subject: Re: init1.C failure under study Date: Sun, 30 Nov 1997 22:31:00 -0000 Message-id: <19971201003055.40038@dgii.com> References: <19971129112737.14113.cygnus.egcs@dgii.com> X-SW-Source: 1997-11/msg00993.html > > This test works on OpenServer ELF, but not COFF. Whether this is > > something in the way sco5.h handles initializers, I can't tell. OK. I've reduced the problem down to a one-line assembly source change that seems to make sense. I just can't find the place in sco5.h (if it is even in sco5.h) that's mishandling this. I've attached the assembly output of the previous example (I may have thrown in another printf or something). The problem seems to be that it's pushing the address of a stupid little function that contains only prologue and epilogue for the ctor instead of the "real" one. If you look at the end, you'll find that .init contains pushl $_GLOBAL_.I.f__Fv This does get called and the do_global_ctors handlers do ineed call this function. Unfortunately, this function is rather nonexciting, though it does point out an optimization opportunity. _GLOBAL_.I.f__Fv: pushl %ebp movl %esp,%ebp movl %ebp,%esp popl %ebp ret If I replace that pushl with a pushl for the address __tcf_0 (the function that seems to really contain the ctor) it passes the test. Interestingly, the only reference to __tcf_0 is in an atexit (?!?!) function, so that doesn't make any sense either. My gut tells me that something in the coff/elf handling in sco5.h is tripping up other things, but I just can't see how anything there differs in any substantial way from what's in the similar svr[34].h files... Any clues? Oh, Jason. The presence of HAVE_ATEXIT doesn't seem to change anything here... RJL .file "init1.C" .version "01.01" / GNU C++ version egcs-2.90.19 971127 (gcc2-970802 experimental) (i586-pc-sco3.2v5.0.4) compiled by GNU C version egcs-2.90.19 971127 (gcc2-970802 experimental). / options passed: -mcoff -O -fno-exceptions / options enabled: -fdefer-pop -fthread-jumps -fpeephole -ffunction-cse / -finline -fkeep-static-consts -fpcc-struct-return -fsjlj-exceptions / -fcommon -fverbose-asm -fgnu-linker -falias-check -fargument-alias / -m80387 -mhard-float -mno-soft-float -mieee-fp -mfp-ret-in-387 / -mschedule-prologue -mcoff -mcpu=pentium -march=pentium gcc2_compiled.: __gnu_compiled_cplusplus: .text .LC0: .string "Dtor\n" .LC1: .string " Ctor: Bump count to %d\n" .LC2: .string "Called f\n" .data .align 4 .lcomm a.6,1 .align 4 .lcomm _.tmp_0.7,4 .text .align 4 __tcf_0: pushl %ebp movl %esp,%ebp incl count movl count,%eax pushl %eax pushl $.LC1 call printf movl %ebp,%esp popl %ebp ret .align 4 .globl f__Fv f__Fv: pushl %ebp movl %esp,%ebp pushl $.LC2 call printf addl $4,%esp cmpl $0,_.tmp_0.7 jne .L18 movl $1,_.tmp_0.7 pushl $__tcf_0 call atexit .L18: movl %ebp,%esp popl %ebp ret .LC3: .string "Construct a\n" .data .align 4 .lcomm a.12,1 .align 4 .lcomm _.tmp_1.13,4 .text .align 4 __tcf_1: pushl %ebp movl %esp,%ebp incl count movl count,%eax pushl %eax pushl $.LC1 call printf movl %ebp,%esp popl %ebp ret .align 4 .globl g__Fv g__Fv: pushl %ebp movl %esp,%ebp pushl $.LC3 call printf addl $4,%esp cmpl $0,_.tmp_1.13 jne .L27 movl $1,_.tmp_1.13 pushl $__tcf_1 call atexit .L27: movl %ebp,%esp popl %ebp ret .LC4: .string "main: pref\n" .LC5: .string "main: postf\n" .align 4 .globl main main: pushl %ebp movl %esp,%ebp pushl $.LC4 call printf call f__Fv pushl $.LC5 call printf xorl %eax,%eax movl %ebp,%esp popl %ebp ret .globl c .data c: .set .,.+1 .text .align 4 .globl _GLOBAL_.D.f__Fv _GLOBAL_.D.f__Fv: pushl %ebp movl %esp,%ebp pushl $.LC0 call printf addl $4,%esp cmpl $1,count je .L35 pushl $1 call _exit .align 4 .L35: movl %ebp,%esp popl %ebp ret .section .fini, "x" .long _GLOBAL_.D.f__Fv .text .align 4 .globl _GLOBAL_.I.f__Fv _GLOBAL_.I.f__Fv: pushl %ebp movl %esp,%ebp movl %ebp,%esp popl %ebp ret .section .init ,"x" / pushl $_GLOBAL_.I.f__Fv pushl $__tcf_0 .globl count .data .align 4 count: .set .,.+4 .ident "GCC: (GNU) egcs-2.90.19 971127 (gcc2-970802 experimental)" #include extern "C" int printf(const char *, ...); int count; extern "C" void _exit(int); struct C { ~C() {printf("Dtor\n"); if (count != 1) _exit(1); } } c; class A { public: ~A () { ++count; printf(" Ctor: Bump count to %d\n", count);} }; void f() { printf("Called f\n"); // static A a; static A a; } void g() { // Since this isn't constructed, we can't destruct it. printf("Construct a\n"); static A a; } int main () { printf("main: pref\n"); f(); printf("main: postf\n"); }