c-family: -Waddress-of-packed-member and casts

-Waddress-of-packed-member, in addition to the documented warning about
actually 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.

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.
This commit is contained in:
Jason Merrill
2023-11-22 13:20:58 -05:00
parent 7362543f00
commit b7e4a4c626
8 changed files with 19 additions and 102 deletions

View File

@@ -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. */

View File

@@ -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 } } } */

View File

@@ -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 } */
}

View File

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

View File

@@ -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 } */

View File

@@ -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 } */

View File

@@ -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 } */

View File

@@ -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 } */