On Mon, Mar 24, 2008 at 02:05:14PM -0300, Alvaro Herrera wrote:
> Kurt Roeckx wrote:
> > On Thu, Mar 20, 2008 at 06:53:27PM -0400, Tom Lane wrote:
> > > Kurt Roeckx <kurt@roeckx.be> writes:
> > > > I did some tests with gcc 4.3 on the branches from 7.4 to 8.3 and head.
> > > > 8.3 and head don't have a problem. All others failed in the
> > > > ContribCheck state.
> > >
> > > Bizarre. There doesn't seem to be any significant difference in the seg
> > > code between 8.2 and 8.3, so why is 8.2 failing there?
>
> > Somewhere seg_same is converted from returning a bool to
> > returning a char pointer.
> >
> > returnValue has the value 0xffffff00 for me, which of course is an
> > invalid pointer.
>
> So the difference is in CFLAGS? I do recall reading something about
> these kind of things in the GCC 4.3.0 release notes.
No, this has nothing to do with CFLAGS. It's calling a function which
returns something other than it actually returns.
The code basicly does:
char foo()
{ return 0;
}
char *bar()
{ char *p; char (*f)() = (char *(*)())foo; p = f();return p;
}
foo is:
char foo()
But we called it like it's an:
char *foo()
In our case, foo() contains a function call, and is then checked for == 0.
gcc-4.3 generates such code for that:
0x000000000040052f <foo+19>: test %eax,%eax
0x0000000000400531 <foo+21>: sete %al
While gcc-4.2 generates:
0x000000000040052f <foo+19>: test %eax,%eax
0x0000000000400531 <foo+21>: sete %al
0x0000000000400534 <foo+24>: movzbl %al,%eax
Since it's only returning a char which is 8 bit, it only should change
the lowest part of the register, so it's perfectly valid to do that.
seg_cmp() happened to return -1 (0xffffffff). So seg_same (foo)
happened to change eax to 0xffffff00. And then that gets interpreted
as a pointer, which doesn't make much sense anymore.
Kurt