mirror of
https://github.com/gcc-mirror/gcc.git
synced 2026-05-06 14:59:39 +02:00
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:
@@ -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. */
|
||||
|
||||
@@ -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 } } } */
|
||||
|
||||
@@ -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 } */
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 } */
|
||||
@@ -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 } */
|
||||
@@ -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 } */
|
||||
@@ -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 } */
|
||||
|
||||
Reference in New Issue
Block a user