c++/9722: g++ 3.4: structure passing bug

snyder@fnal.gov snyder@fnal.gov
Mon Feb 17 15:06:00 GMT 2003


>Number:         9722
>Category:       c++
>Synopsis:       g++ 3.4: structure passing bug
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    unassigned
>State:          open
>Class:          wrong-code
>Submitter-Id:   net
>Arrival-Date:   Mon Feb 17 15:06:01 UTC 2003
>Closed-Date:
>Last-Modified:
>Originator:     scott snyder
>Release:        3.4 20030210 (experimental)
>Organization:
<organization of PR author (multiple lines)>
>Environment:
System: Linux karma 2.4.19-emp_2419p5a829i #1 Tue Sep 3 17:42:17 EST 2002 i686 unknown
Architecture: i686

	<machine, os, target, libraries (multiple lines)>
host: i686-pc-linux-gnu
build: i686-pc-linux-gnu
target: i686-pc-linux-gnu
configured with: ../gcc/configure --prefix=/usr/local/gcc --enable-threads=posix --enable-long-long
>Description:

gcc generates bad code in the function bar() below for the passing
of the structure to foo().  (Amusingly, the problem shows up only
with optimization off and goes away with optimization on --- but only
because foo() gets inlined with optimization on.)

I expect the program to print `4 5 6'.  Here is what it actually
prints for me:

$ g++ -o x x.cc
$ ./x
1073820864 1073824136 1073824548
$

Here is code generated for the bar() function (with labels unused here
removed for readability):

_Z3barR1B:
        pushl   %ebp
        movl    %esp, %ebp
        pushl   %edi
        pushl   %esi
        pushl   %ebx
        subl    $156, %esp
        movl    8(%ebp), %eax
        movl    %esp, %ecx
        movl    %eax, %edx
        movl    $144, %eax
        movl    8(%esp), %esi
        movl    %eax, 8(%esp)
        movl    4(%esp), %edi
        movl    %edx, 4(%esp)
        movl    (%esp), %ebx
        movl    %ecx, (%esp)
        call    memcpy
        movl    %esi, 8(%esp)
        movl    %edi, 4(%esp)
        movl    %ebx, (%esp)
        call    _Z3foo1B
        addl    $156, %esp
        popl    %ebx
        popl    %esi
        popl    %edi
        popl    %ebp
        ret

It looks like the generated code properly copies the structure
to be passed into the stack, but it then overwrites the
first three words (immediately after the memcpy call).

I do not see this failure in the 3.3 branch.
I also do not see the failure if i adjust the source to be
valid C code and use gcc instead of g++.


>How-To-Repeat:

-----------------------------------
extern "C" int printf(...);
extern "C" void memset(...);

struct B
{
  int f[36];
};


void foo (B b) {printf ("%d %d %d\n", b.f[0], b.f[1], b.f[2]);}


void bar (B& b)
{
  foo (b);
}

int main ()
{
  B b;
  memset (&b.f, 0, sizeof (B));
  b.f[0] = 4;
  b.f[1] = 5;
  b.f[2] = 6;
  bar(b);
  return 0;
}

-----------------------------------

>Fix:
	<how to correct or work around the problem, if known (multiple lines)>
>Release-Note:
>Audit-Trail:
>Unformatted:



More information about the Gcc-bugs mailing list