Tested x86_64-pc-linux-gnu, OK for trunk? -- 8< --
-Waddress-of-packed-member, in addition to the documented warning about taking the address of a packed member, also warns about casting from a pointer to a TYPE_PACKED type to a pointer to a type with greater alignment. This wrongly warns if the source is a pointer to enum when -fshort-enums is on, since that is also represented by TYPE_PACKED. And there's already -Wcast-align to catch casting from pointer to less aligned type (packed or otherwise) to pointer to more aligned type; even apart from the enum problem, this seems like a somewhat arbitrary subset of that warning. Though that isn't currently on by default. So, this patch removes the undocumented type-based warning from -Waddress-of-packed-member. Some of the tests where the warning is desirable I changed to use -Wcast-align=strict instead. The ones that require -Wno-incompatible-pointer-types, I just removed. gcc/c-family/ChangeLog: * c-warn.cc (check_address_or_pointer_of_packed_member): Remove warning based on TYPE_PACKED. gcc/testsuite/ChangeLog: * c-c++-common/Waddress-of-packed-member-1.c: Don't expect a warning on the cast cases. * c-c++-common/pr51628-35.c: Use -Wcast-align=strict. * g++.dg/warn/Waddress-of-packed-member3.C: Likewise. * gcc.dg/pr88928.c: Likewise. * gcc.dg/pr51628-20.c: Removed. * gcc.dg/pr51628-21.c: Removed. * gcc.dg/pr51628-25.c: Removed. --- gcc/c-family/c-warn.cc | 58 +------------------ .../Waddress-of-packed-member-1.c | 12 ++-- gcc/testsuite/c-c++-common/pr51628-35.c | 6 +- .../g++.dg/warn/Waddress-of-packed-member3.C | 8 +-- gcc/testsuite/gcc.dg/pr51628-20.c | 11 ---- gcc/testsuite/gcc.dg/pr51628-21.c | 11 ---- gcc/testsuite/gcc.dg/pr51628-25.c | 9 --- gcc/testsuite/gcc.dg/pr88928.c | 6 +- 8 files changed, 19 insertions(+), 102 deletions(-) delete mode 100644 gcc/testsuite/gcc.dg/pr51628-20.c delete mode 100644 gcc/testsuite/gcc.dg/pr51628-21.c delete mode 100644 gcc/testsuite/gcc.dg/pr51628-25.c diff --git a/gcc/c-family/c-warn.cc b/gcc/c-family/c-warn.cc index d2938b91043..2a399ba6d14 100644 --- a/gcc/c-family/c-warn.cc +++ b/gcc/c-family/c-warn.cc @@ -2991,10 +2991,9 @@ check_alignment_of_packed_member (tree type, tree field, bool rvalue) return NULL_TREE; } -/* Return struct or union type if the right hand value, RHS: - 1. Is a pointer value which isn't aligned to a pointer type TYPE. - 2. Is an address which takes the unaligned address of packed member - of struct or union when assigning to TYPE. +/* Return struct or union type if the right hand value, RHS + is an address which takes the unaligned address of packed member + of struct or union when assigning to TYPE. Otherwise, return NULL_TREE. */ static tree @@ -3021,57 +3020,6 @@ check_address_or_pointer_of_packed_member (tree type, tree rhs) type = TREE_TYPE (type); - if (TREE_CODE (rhs) == PARM_DECL - || VAR_P (rhs) - || TREE_CODE (rhs) == CALL_EXPR) - { - tree rhstype = TREE_TYPE (rhs); - if (TREE_CODE (rhs) == CALL_EXPR) - { - rhs = CALL_EXPR_FN (rhs); /* Pointer expression. */ - if (rhs == NULL_TREE) - return NULL_TREE; - rhs = TREE_TYPE (rhs); /* Pointer type. */ - /* We could be called while processing a template and RHS could be - a functor. In that case it's a class, not a pointer. */ - if (!rhs || !POINTER_TYPE_P (rhs)) - return NULL_TREE; - rhs = TREE_TYPE (rhs); /* Function type. */ - rhstype = TREE_TYPE (rhs); - if (!rhstype || !POINTER_TYPE_P (rhstype)) - return NULL_TREE; - rvalue = true; - } - if (rvalue && POINTER_TYPE_P (rhstype)) - rhstype = TREE_TYPE (rhstype); - while (TREE_CODE (rhstype) == ARRAY_TYPE) - rhstype = TREE_TYPE (rhstype); - if (TYPE_PACKED (rhstype)) - { - unsigned int type_align = min_align_of_type (type); - unsigned int rhs_align = min_align_of_type (rhstype); - if (rhs_align < type_align) - { - auto_diagnostic_group d; - location_t location = EXPR_LOC_OR_LOC (rhs, input_location); - if (warning_at (location, OPT_Waddress_of_packed_member, - "converting a packed %qT pointer (alignment %d) " - "to a %qT pointer (alignment %d) may result in " - "an unaligned pointer value", - rhstype, rhs_align, type, type_align)) - { - tree decl = TYPE_STUB_DECL (rhstype); - if (decl) - inform (DECL_SOURCE_LOCATION (decl), "defined here"); - decl = TYPE_STUB_DECL (type); - if (decl) - inform (DECL_SOURCE_LOCATION (decl), "defined here"); - } - } - } - return NULL_TREE; - } - tree context = NULL_TREE; /* Check alignment of the object. */ diff --git a/gcc/testsuite/c-c++-common/Waddress-of-packed-member-1.c b/gcc/testsuite/c-c++-common/Waddress-of-packed-member-1.c index 95a376664da..0f5188df70a 100644 --- a/gcc/testsuite/c-c++-common/Waddress-of-packed-member-1.c +++ b/gcc/testsuite/c-c++-common/Waddress-of-packed-member-1.c @@ -52,12 +52,12 @@ void foo (void) f0 = *&__real__ t0.f; /* { dg-bogus "may result in an unaligned pointer value" } */ f0 = *&__imag__ t0.f; /* { dg-bogus "may result in an unaligned pointer value" } */ i1 = (&t0.c, (int*) 0); /* { dg-bogus "may result in an unaligned pointer value" } */ - t2 = (struct t**) t10; /* { dg-warning "may result in an unaligned pointer value" "" { target { ! default_packed } } } */ - t2 = (struct t**) t100; /* { dg-warning "may result in an unaligned pointer value" "" { target { ! default_packed } } } */ - t2 = (struct t**) t1; /* { dg-warning "may result in an unaligned pointer value" "" { target { ! default_packed } } } */ - t2 = (struct t**) bar(); /* { dg-warning "may result in an unaligned pointer value" "" { target { ! default_packed } } } */ - t2 = (struct t**) baz(); /* { dg-warning "may result in an unaligned pointer value" "" { target { ! default_packed } } } */ - t2 = (struct t**) bazz(); /* { dg-warning "may result in an unaligned pointer value" "" { target { ! default_packed } } } */ + t2 = (struct t**) t10; /* { dg-bogus "may result in an unaligned pointer value" } */ + t2 = (struct t**) t100; /* { dg-bogus "may result in an unaligned pointer value" } */ + t2 = (struct t**) t1; /* { dg-bogus "may result in an unaligned pointer value" } */ + t2 = (struct t**) bar(); /* { dg-bogus "may result in an unaligned pointer value" } */ + t2 = (struct t**) baz(); /* { dg-bogus "may result in an unaligned pointer value" } */ + t2 = (struct t**) bazz(); /* { dg-bogus "may result in an unaligned pointer value" } */ i1 = &t0.b; /* { dg-warning "may result in an unaligned pointer value" "" { target { ! default_packed } } } */ i1 = &t1->b; /* { dg-warning "may result in an unaligned pointer value" "" { target { ! default_packed } } } */ i1 = &t10[0].b; /* { dg-warning "may result in an unaligned pointer value" "" { target { ! default_packed } } } */ diff --git a/gcc/testsuite/c-c++-common/pr51628-35.c b/gcc/testsuite/c-c++-common/pr51628-35.c index fa37d99beb7..a88c19ea0df 100644 --- a/gcc/testsuite/c-c++-common/pr51628-35.c +++ b/gcc/testsuite/c-c++-common/pr51628-35.c @@ -1,6 +1,6 @@ /* PR c/51628. */ /* { dg-do compile } */ -/* { dg-options "-O" } */ +/* { dg-options "-O -Wcast-align=strict" } */ struct B { int i; }; struct C { struct B b; } __attribute__ ((packed)); @@ -12,12 +12,12 @@ long * foo1 (void) { return (long *) p; -/* { dg-warning "may result in an unaligned pointer value" "" { target { ! default_packed } } .-1 } */ +/* { dg-warning "increases required alignment" "" { target { ! default_packed } } .-1 } */ } long * foo2 (void) { return (long *) bar (); -/* { dg-warning "may result in an unaligned pointer value" "" { target { ! default_packed } } .-1 } */ +/* { dg-warning "increases required alignment" "" { target { ! default_packed } } .-1 } */ } diff --git a/gcc/testsuite/g++.dg/warn/Waddress-of-packed-member3.C b/gcc/testsuite/g++.dg/warn/Waddress-of-packed-member3.C index aeffb969c01..28dd05d366c 100644 --- a/gcc/testsuite/g++.dg/warn/Waddress-of-packed-member3.C +++ b/gcc/testsuite/g++.dg/warn/Waddress-of-packed-member3.C @@ -1,5 +1,5 @@ // { dg-do compile { target { ! default_packed } } } -// Test that -Waddress-of-packed-member works with member functions. +// { dg-additional-options -Wcast-align=strict } struct S { char c; @@ -16,8 +16,8 @@ S** f () { S **s; - s = reinterpret_cast<S**>(foo ()); // { dg-warning "converting a packed" } - s = reinterpret_cast<S**>(x.memfn ()); // { dg-warning "converting a packed" } - s = reinterpret_cast<S**>(X::smemfn ()); // { dg-warning "converting a packed" } + s = reinterpret_cast<S**>(foo ()); // { dg-warning "increases required alignment" } + s = reinterpret_cast<S**>(x.memfn ()); // { dg-warning "increases required alignment" } + s = reinterpret_cast<S**>(X::smemfn ()); // { dg-warning "increases required alignment" } return s; } diff --git a/gcc/testsuite/gcc.dg/pr51628-20.c b/gcc/testsuite/gcc.dg/pr51628-20.c deleted file mode 100644 index 2249d85098b..00000000000 --- a/gcc/testsuite/gcc.dg/pr51628-20.c +++ /dev/null @@ -1,11 +0,0 @@ -/* PR c/51628. */ -/* { dg-do compile } */ -/* { dg-options "-O -Wno-incompatible-pointer-types" } */ - -struct B { int i; }; -struct C { struct B b; } __attribute__ ((packed)); - -extern struct C *p; - -long* g8 (void) { return p; } -/* { dg-warning "may result in an unaligned pointer value" "" { target { ! default_packed } } .-1 } */ diff --git a/gcc/testsuite/gcc.dg/pr51628-21.c b/gcc/testsuite/gcc.dg/pr51628-21.c deleted file mode 100644 index f1adbe64002..00000000000 --- a/gcc/testsuite/gcc.dg/pr51628-21.c +++ /dev/null @@ -1,11 +0,0 @@ -/* PR c/51628. */ -/* { dg-do compile } */ -/* { dg-options "-O -Wno-incompatible-pointer-types" } */ - -struct B { int i; }; -struct C { struct B b; } __attribute__ ((packed)); - -extern struct C p[]; - -long* g8 (void) { return p; } -/* { dg-warning "may result in an unaligned pointer value" "" { target { ! default_packed } } .-1 } */ diff --git a/gcc/testsuite/gcc.dg/pr51628-25.c b/gcc/testsuite/gcc.dg/pr51628-25.c deleted file mode 100644 index f00d9b1bcac..00000000000 --- a/gcc/testsuite/gcc.dg/pr51628-25.c +++ /dev/null @@ -1,9 +0,0 @@ -/* PR c/51628. */ -/* { dg-do compile } */ -/* { dg-options "-O -Wno-incompatible-pointer-types" } */ - -struct B { int i; }; -struct C { struct B b; } __attribute__ ((packed)); - -long* g8 (struct C *p) { return p; } -/* { dg-warning "may result in an unaligned pointer value" "" { target { ! default_packed } } .-1 } */ diff --git a/gcc/testsuite/gcc.dg/pr88928.c b/gcc/testsuite/gcc.dg/pr88928.c index 0b6c1d70f05..1d176d6d51d 100644 --- a/gcc/testsuite/gcc.dg/pr88928.c +++ b/gcc/testsuite/gcc.dg/pr88928.c @@ -1,6 +1,6 @@ -/* { dg-do compile } */ -/* { dg-options "-Wno-pedantic -Waddress-of-packed-member" } */ +/* { dg-do compile { target { ! default_packed } } } */ +/* { dg-options "-Wno-pedantic -Waddress-of-packed-member -Wcast-align=strict" } */ struct a { } __attribute__((__packed__)); void c (struct a **); void d (const struct a *b) { c ((struct a **) b); } -/* { dg-warning "may result in an unaligned pointer value" "" { target { ! default_packed } } .-1 } */ +/* { dg-warning "increases required alignment" "" { target *-*-* } .-1 } */ base-commit: 65bd6de0de57abc86931a5e0b9a8d453ad530004 -- 2.39.3