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