Sorry, I forgot to attach the file...
> 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
/*
* Minimum definitions copied from PostgreSQL to make the
* test self-contained.
*/
#define nodeTag(nodeptr) (((const Node*)(nodeptr))->type)
#define IsA(nodeptr,_type_) (nodeTag(nodeptr) == T_##_type_)
typedef enum NodeTag
{
T_Invalid = 0,
T_List = 1
} NodeTag;
typedef struct Node
{
NodeTag type;
} Node;
/* Home brew node */
typedef struct Foo
{
NodeTag type;
int d;
} Foo;
static int sub(void)
{
Foo f;
Foo *fp = &f;
f.type = T_List;
/* strict aliasing rule error */
if (IsA(&f, List))
return 1;
/* This is ok */
if (IsA(fp, List))
return 1;
return 0;
}