Re: compile warning

From: Bruce Momjian <pgman(at)candle(dot)pha(dot)pa(dot)us>
To: Alvaro Herrera <alvherre(at)dcc(dot)uchile(dot)cl>
Cc: Hackers <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: compile warning
Date: 2003-10-10 18:34:01
Message-ID: 200310101834.h9AIY1702669@candle.pha.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

Alvaro Herrera wrote:
> On Thu, Oct 09, 2003 at 11:51:09PM -0400, Bruce Momjian wrote:
> > Alvaro Herrera wrote:
> > > I'm seeing this compile warning on today's CVS tip:
> > >
> > > $ make src/backend/commands/tablecmds.o
> > > gcc -O2 -g -Wall -Wmissing-prototypes -Wmissing-declarations -I./src/include -D_GNU_SOURCE -c -o src/backend/commands/tablecmds.o src/backend/commands/tablecmds.c
> > > src/backend/commands/tablecmds.c: In function `validateForeignKeyConstraint':
> > > src/backend/commands/tablecmds.c:3528: warning: dereferencing type-punned pointer will break strict-aliasing rules
> >
> > If you change the offending line to:
> >
> > fcinfo.context = (struct Node *) &trigdata;
> >
> > I know it shouldn't make a difference, but it is worth a try.
>
> Nope, same warning. I don't know what it means though. I tried some
> other things to correct it, but I can't find exactly what it's
> complaining about. What is a "type-punned pointer"?
>
> Looking in Google finds this thread first:
> http://www.mail-archive.com/freebsd-current(at)freebsd(dot)org/msg58957.html
> which is full of a very ugly kernel macro (I'm happy to stay away from
> that):
>
> http://www.mail-archive.com/freebsd-current(at)freebsd(dot)org/msg58957.html
>
>
> This other guy actually posted an useful excerpt from the GCC manpage:
> http://www.ethereal.com/lists/ethereal-dev/200309/msg00342.html
>
> So, I still don't understand what's the noise about. However I think
> there's no way to silence the warning without uglifying the structs a
> lot by means of some union.

I am still confused. I understand the example listed in the last URL:

union a_union {
int i;
double d;
};

int f() {
a_union t;
t.d = 3.0;
return t.i;
}

will work fine because you are accessing the values through the union.
However in this example, also from that URL:

int f() {
a_union t;
int* ip;
t.d = 3.0;
ip = &t.i;
return *ip;
}

there is a problem because it assumes that the int and double _start_
at the same address in the structure. It is probabably a bad idea to be
taking passing pointers out of a union.

However, we aren't using unions in the query being complainted about.

In our code mentioned above, we have:

> > fcinfo.context = (Node *) &trigdata;

We are taking the address of a structure (not a union), but we are
assuming that a "struct TriggerData" pointer can be accessed through a
"struct Node" pointer. Now, both structures begin with a NodeTag
element, so it should be OK, but I guess the compiler guys don't know
that. However, I thought the cast shouldn't cause a problem at all.

Can someone with gcc 3.3.1 make up a little test program to illustrate
the bug? Does taking the adddress of any structure an casting it cause
this warning? I would think not because we must do that lots of places
in our code.

This seems to be a bug in gcc-3.3.1. -fstrict-aliasing is enabled by
-O2 or higher optimization in gcc 3.3.1.

Now that I think of it, they might be talking about an optimization
called register aliasing, where they are taking the structure and
mapping it to a CPU register for some optimization, and what we are
doing is to store a different structure in there that will not fit in a
register. A Node will fit in a register (it is only an enum) but the
TriggerData structure will not, meaning the code has to spill the
register to memory, then access the full structure, or something like
that.

Here are the places reported to generated warnings in our code by the
Cygwin guys:

tablecmds.c:3528: warning: dereferencing type-punned pointer will break strict-aliasing rules
execQual.c:749: warning: dereferencing type-punned pointer will break strict-aliasing rules
execQual.c:995: warning: dereferencing type-punned pointer will break strict-aliasing rules
pg_shmem.c:368: warning: passing arg 1 of `shmdt' from incompatible pointer type
proc.c:1016: warning: dereferencing type-punned pointer will break strict-aliasing rules
proc.c:1057: warning: dereferencing type-punned pointer will break strict-aliasing rules
proc.c:1123: warning: dereferencing type-punned pointer will break strict-aliasing rules
command.c:1283: warning: dereferencing type-punned pointer will break strict-aliasing rules

Looking at the proc.c cases, we have:

MemSet(&timeval, 0, sizeof(struct itimerval));

MemSet is passing struct itimerval * to an *int32, again a case of passing
a structure pointer to something to a data type that will fit in a
register.

--
Bruce Momjian | http://candle.pha.pa.us
pgman(at)candle(dot)pha(dot)pa(dot)us | (610) 359-1001
+ If your life is a hard drive, | 13 Roberts Road
+ Christ can be your backup. | Newtown Square, Pennsylvania 19073

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Gaetano Mendola 2003-10-10 18:44:04 rt_sigprocmask
Previous Message Peter Eisentraut 2003-10-10 17:54:25 Re: last beta version to require initdb