Source: typedef union u { unsigned i; unsigned short s[2]; unsigned char c[4]; } u; char c[4] __attribute__((aligned)); short s[2] __attribute__((aligned)); int f1() { return ((union u*)s)->i; } int f2() { return ((union u*)c)->i; } Using gcc 4.5: > gcc -O3 -fstrict-aliasing -Wall -S wstrict_aliasing_char.c wstrict_aliasing_char.c: In function 'f2': wstrict_aliasing_char.c:13:17: warning: dereferencing type-punned pointer will break strict-aliasing rules I would expect either both or neither of the functions to warn, since pointer casting to unions is given in the manual as something that violates strict-aliasing, although gcc doesn't seem to actually take advantage of this. Instead, it looks like the warning is hardcoded to apply to a cast from char (c-common.c:1746 in r1554411): alias_set_type set1 = get_alias_set (TREE_TYPE (TREE_OPERAND (expr, 0))); alias_set_type set2 = get_alias_set (TREE_TYPE (type)); if (set1 != set2 && set2 != 0 && (set1 == 0 || !alias_sets_conflict_p (set1, set2))) { warning (OPT_Wstrict_aliasing, "dereferencing type-punned " "pointer will break strict-aliasing rules"); return true; } This came up during some x264 work, but it's taken care of now with some __attribute__((may_alias)).
!alias_sets_conflict_p (set1, set2) should really be alias_set_subset_of with all the added false positives from the very imprecise frontend code that this would cause. Thus, the cast from short[] also should warn.
Fixed in GCC 7.2.0 and above by the patch which fixed PR 80593.