The following patch adjusts strict_aliasing_warning to use proper alias_set_subset_of instead of relying on alias_sets_conflict_p as after the PR66110 fix aggregates with a char[] member do not automatically behave like having alias-set zero. As a side-effect the test will be somewhat stricter as well accessing a 'long' with a struct { int i; long l; } * will now warn while it previously didn't:
struct S { int i; long l; }; long x; struct S foo () { return *(struct S *)&x; } now warns: t.c: In function ‘foo’: t.c:3:35: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing] struct S foo () { return *(struct S *)&x; } ^ Bootstrap and regtest running on x86_64-unknown-linux-gnu, ok for trunk? Thanks, Richard. 2016-03-03 Richard Biener <rguent...@suse.de> PR c++/70054 * c-common.c (strict_aliasing_warning): Use alias_set_subset_of instead of alias_sets_conflict_p. * g++.dg/warn/Wstrict-aliasing-bogus-union-2.C: New testcase. * gcc.dg/Wstrict-aliasing-struct-member.c: New testcase. Index: gcc/c-family/c-common.c =================================================================== *** gcc/c-family/c-common.c (revision 233902) --- gcc/c-family/c-common.c (working copy) *************** strict_aliasing_warning (tree otype, tre *** 1568,1574 **** 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"); --- 1568,1574 ---- alias_set_type set2 = get_alias_set (TREE_TYPE (type)); if (set1 != set2 && set2 != 0 ! && (set1 == 0 || !alias_set_subset_of (set2, set1))) { warning (OPT_Wstrict_aliasing, "dereferencing type-punned " "pointer will break strict-aliasing rules"); Index: gcc/testsuite/g++.dg/warn/Wstrict-aliasing-bogus-union-2.C =================================================================== *** gcc/testsuite/g++.dg/warn/Wstrict-aliasing-bogus-union-2.C (revision 0) --- gcc/testsuite/g++.dg/warn/Wstrict-aliasing-bogus-union-2.C (working copy) *************** *** 0 **** --- 1,14 ---- + /* { dg-do compile { target c++11 } } */ + /* { dg-options "-Wstrict-aliasing=2 -O2 -Wall" } */ + + #include <type_traits> + + struct foo + { + std::aligned_storage<sizeof(long), alignof(long)>::type raw; + + long& cooked() + { + return *static_cast<long*>(static_cast<void*>(&raw)); /* { dg-bogus "strict-aliasing" } */ + } + }; Index: gcc/testsuite/gcc.dg/Wstrict-aliasing-struct-member.c =================================================================== --- gcc/testsuite/gcc.dg/Wstrict-aliasing-struct-member.c (revision 0) +++ gcc/testsuite/gcc.dg/Wstrict-aliasing-struct-member.c (working copy) @@ -0,0 +1,6 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -Wall" } */ + +struct S { int i; long l; }; +long x; +struct S foo () { return *(struct S *)&x; } /* { dg-warning "will break strict-aliasing" } */