Re: warning: dereferencing type-punned pointer

From: Tatsuo Ishii <ishii(at)postgresql(dot)org>
To: peter(at)eisentraut(dot)org
Cc: tgl(at)sss(dot)pgh(dot)pa(dot)us, pgsql-hackers(at)postgresql(dot)org
Subject: Re: warning: dereferencing type-punned pointer
Date: 2024-07-26 07:11:32
Message-ID: 20240726.161132.1864131832066149208.ishii@postgresql.org
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

> On 24.07.24 20:09, Tom Lane wrote:
>> Peter Eisentraut<peter(at)eisentraut(dot)org> writes:
>>> On 24.07.24 16:05, Tom Lane wrote:
>>>> I'm not very thrilled with these changes. It's not apparent why
>>>> your compiler is warning about these usages of IsA and not any other
>>>> ones,
>>> I think one difference is that normally IsA is called on a Node *
>>> (since
>>> you call IsA to decide what to cast it to), but in this case it's
>>> called
>>> on a pointer that is already of type ErrorSaveContext *.
>> Hmm. But there are boatloads of places where we call IsA on a
>> pointer of type Expr *, or sometimes other things. Why aren't
>> those triggering the same warning?
>
> It must have to do with the fact that the escontext field in
> JsonExprState has the object inline, not as a pointer. AIUI, with
> dynamically allocated objects you have more liberties about what type
> to interpret them as than with actually declared objects.

I don't agree. I think the compiler just dislike that nodeTag macro's
argument is a pointer created by '&' operator in this case:

#define nodeTag(nodeptr) (((const Node*)(nodeptr))->type)

If we just give a pointer variable either it's type is Node * or
ErrorSaveContext * to nodeTag macro, the compiler becomes happy.

Moreover I think whether the object is inline or not is
irrelevant. Attached is a self contained test case. In the program:

if (IsA(&f, List))

produces the strict aliasing rule violation but

if (IsA(fp, List))

does not. Here "f" is an object defined as:

typedef struct Foo
{
NodeTag type;
int d;
} Foo;

Foo f;

and fp is defined as:

Foo *fp = &f;

$ gcc -Wall -O2 -c strict2.c
strict2.c: In function ‘sub’:
strict2.c:1:29: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
1 | #define nodeTag(nodeptr) (((const Node*)(nodeptr))->type)
| ~^~~~~~~~~~~~~~~~~~~~~~~
strict2.c:2:31: note: in expansion of macro ‘nodeTag’
2 | #define IsA(nodeptr,_type_) (nodeTag(nodeptr) == T_##_type_)
| ^~~~~~~
strict2.c:26:6: note: in expansion of macro ‘IsA’
26 | if (IsA(&f, List))
| ^~~
At top level:
strict2.c:21:12: warning: ‘sub’ defined but not used [-Wunused-function]
21 | static int sub(void)
| ^~~

> If you change the member to a pointer
>
> - ErrorSaveContext escontext;
> + ErrorSaveContext *escontext;
> } JsonExprState;
>
> and make the required adjustments elsewhere in the code, the warning
> goes away.

I think this is not necessary. Just my patch in the upthread is enough.

Best reagards,
--
Tatsuo Ishii
SRA OSS LLC
English: http://www.sraoss.co.jp/index_en/
Japanese:http://www.sraoss.co.jp

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Tatsuo Ishii 2024-07-26 07:49:10 Re: warning: dereferencing type-punned pointer
Previous Message Yugo Nagata 2024-07-26 07:07:14 EphemeralNamedRelation and materialized view