Hi, gcc 4.3.3 -> gcc 4.6.latest target native x86 m32 I did a quick bugzilla search, and archive search and found nothing relevent. I've a class with overloaded functions, one of which is virtual, and code is being generated to call the incorrect member function on the x86 32-bit architecture. The code is generated correctly on the x86 64-bit architecture. ---- Class:----- class c_logger { bool l_debug; public: c_logger(bool d) { l_debug = d; } virtual ~c_logger(void) {}; void log(const char *, ...) __attribute__((format(printf, 2, 3))); size_t trace(const char *, ...) __attribute__((format(printf, 2, 3))); virtual void log(const char *, va_list) = 0; virtual size_t trace(const char *, va_list) = 0; void set_tracing(bool d=false) { l_debug = d; } bool is_tracing(void) { return l_debug; } }; ----------------- The code in question: ---------------- bool c_telcom_dlp::control(int argc, const char **argv, c_logger *lp) { ulong unit = parse_unit(argv[0]); if (argc < 2) { if (unit == INVALID_UNIT) { unit = 0; } lp->log("%4.4lu/%2.2lu Argument required for control command\n", d_channel, unit); return true; } if (strcasecmp(argv[1], "line") == 0) { char *cp; ulong line; if (unit != 0) { if (unit == INVALID_UNIT) { ====> lp->log("%s Unit # must be supplied\n", t_dlp_name); } else { lp->log("%s Invalid Unit\n", t_dlp_name); } return true; } ---------------- The first call to c_logger::log(const char *, ...) is generated as: lp->log("%4.4lu/%2.2lu Argument required for control command\n", d_channel, unit); .globl _ZN12c_telcom_dlp7controlEiPPKcP8c_logger .type _ZN12c_telcom_dlp7controlEiPPKcP8c_logger, @function _ZN12c_telcom_dlp7controlEiPPKcP8c_logger: .LFB579: .loc 13 1074 0 pushl %ebp .LCFI139: movl %esp, %ebp .LCFI140: pushl %edi .LCFI141: pushl %esi .LCFI142: pushl %ebx .LCFI143: subl $236, %esp .LCFI144: call __i686.get_pc_thunk.bx addl $_GLOBAL_OFFSET_TABLE_, %ebx .LBB9: .loc 13 1076 0 movl 16(%ebp), %eax movl (%eax), %eax movl 8(%ebp), %edx movl %eax, 4(%esp) movl %edx, (%esp) call _ZN5c_dlp10parse_unitEPKc@PLT movl %eax, -64(%ebp) .loc 13 1078 0 cmpl $1, 12(%ebp) jg .L132 .loc 13 1079 0 cmpl $65535, -64(%ebp) jne .L133 .loc 13 1080 0 movl $0, -64(%ebp) .L133: .loc 13 1083 0 movl 8(%ebp), %eax movl 208(%eax), %edx movl -64(%ebp), %eax movl %eax, 12(%esp) movl %edx, 8(%esp) leal .LC7@GOTOFF(%ebx), %eax movl %eax, 4(%esp) movl 20(%ebp), %eax movl %eax, (%esp) ====> call _ZN8c_logger3logEPKcz@PLT .loc 13 1084 0 movb $1, -194(%ebp) jmp .L134 ----------------------------- The second call to c_logger::log (the marked line above): ====> lp->log("%s Unit # must be supplied\n", t_dlp_name); .LBB10: .loc 13 1147 0 cmpl $0, -64(%ebp) je .L137 .loc 13 1148 0 cmpl $65535, -64(%ebp) jne .L138 .loc 13 1149 0 movl 20(%ebp), %eax movl (%eax), %eax addl $8, %eax movl (%eax), %edx movl 8(%ebp), %eax addl $374, %eax movl %eax, 8(%esp) leal .LC12@GOTOFF(%ebx), %eax # %s Unit # must be supplied\n movl %eax, 4(%esp) movl 20(%ebp), %eax movl %eax, (%esp) ====> call *%edx The second invocation is invoking the virtual member function c_logger::log(const char *, va_list) instead of the base-class c_logger::log(const char *, ...) member. The result is a segmentation violation because the va_args structure hasn't been initialized. Adding an additional argument to the second lp->log() call will cause the correct (and working) code to be generated. t_dlp_name (the single argument to the second log call) is a data member in the class calling lp->log() and is defined as: char t_dlp_name[MAX_DLP_NAME+1]; I've compiled this with 4.3.3 and the most recent 4.6 from subversion and in both cases the virtual function is called when the base member should be called. thanks for any pointers, scott