Re: warning: dereferencing type-punned pointer - Mailing list pgsql-hackers

From Tatsuo Ishii
Subject Re: warning: dereferencing type-punned pointer
Date
Msg-id 20240726.161132.1864131832066149208.ishii@postgresql.org
Whole thread Raw
In response to Re: warning: dereferencing type-punned pointer  (Peter Eisentraut <peter@eisentraut.org>)
Responses Re: warning: dereferencing type-punned pointer
List pgsql-hackers
> On 24.07.24 20:09, Tom Lane wrote:
>> Peter Eisentraut<peter@eisentraut.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

pgsql-hackers by date:

Previous
From: Yugo Nagata
Date:
Subject: EphemeralNamedRelation and materialized view
Next
From: Tatsuo Ishii
Date:
Subject: Re: warning: dereferencing type-punned pointer