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
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 |