re PR c/88928 (ICE segfault in check_address_or_pointer_of_packed_member since r268075)
2019-01-21 Bernd Edlinger <bernd.edlinger@hotmail.de> PR c/88928 * c-warn.c (check_alignment_of_packed_member): Add a boolean parameter for rvalue context. Handle rvalues correctly. Use min_align_of_type instead of TYPE_ALIGN. (check_address_or_pointer_of_packed_member): Handle rvalues coorrectly. Use min_align_of_type instead of TYPE_ALIGN_UNIT. Check for NULL pointer from TYPE_STUB_DECL. testsuite: 2019-01-21 Bernd Edlinger <bernd.edlinger@hotmail.de> PR c/88928 * c-c++-common/Waddress-of-packed-member-1.c: New test case. * gcc.dg/pr88928.c: New test case. From-SVN: r268118
This commit is contained in:
parent
0fba41e0f0
commit
f3a18a5c6c
@ -1,3 +1,13 @@
|
||||
2019-01-21 Bernd Edlinger <bernd.edlinger@hotmail.de>
|
||||
|
||||
PR c/88928
|
||||
* c-warn.c (check_alignment_of_packed_member): Add a boolean parameter
|
||||
for rvalue context. Handle rvalues correctly. Use min_align_of_type
|
||||
instead of TYPE_ALIGN.
|
||||
(check_address_or_pointer_of_packed_member): Handle rvalues coorrectly.
|
||||
Use min_align_of_type instead of TYPE_ALIGN_UNIT. Check for NULL
|
||||
pointer from TYPE_STUB_DECL.
|
||||
|
||||
2019-01-21 Richard Biener <rguenther@suse.de>
|
||||
|
||||
PR tree-optimization/88934
|
||||
|
@ -35,6 +35,7 @@ along with GCC; see the file COPYING3. If not see
|
||||
#include "gimplify.h"
|
||||
#include "c-family/c-indentation.h"
|
||||
#include "calls.h"
|
||||
#include "stor-layout.h"
|
||||
|
||||
/* Print a warning if a constant expression had overflow in folding.
|
||||
Invoke this function on every expression that the language
|
||||
@ -2688,25 +2689,26 @@ warn_for_multistatement_macros (location_t body_loc, location_t next_loc,
|
||||
}
|
||||
|
||||
/* Return struct or union type if the alignment of data memeber, FIELD,
|
||||
is less than the alignment of TYPE. Otherwise, return NULL_TREE. */
|
||||
is less than the alignment of TYPE. Otherwise, return NULL_TREE.
|
||||
If RVALUE is true, only arrays evaluate to pointers. */
|
||||
|
||||
static tree
|
||||
check_alignment_of_packed_member (tree type, tree field)
|
||||
check_alignment_of_packed_member (tree type, tree field, bool rvalue)
|
||||
{
|
||||
/* Check alignment of the data member. */
|
||||
if (TREE_CODE (field) == FIELD_DECL
|
||||
&& (DECL_PACKED (field)
|
||||
|| TYPE_PACKED (TREE_TYPE (field))))
|
||||
&& (DECL_PACKED (field) || TYPE_PACKED (TREE_TYPE (field)))
|
||||
&& (!rvalue || TREE_CODE (TREE_TYPE (field)) == ARRAY_TYPE))
|
||||
{
|
||||
/* Check the expected alignment against the field alignment. */
|
||||
unsigned int type_align = TYPE_ALIGN (type);
|
||||
unsigned int type_align = min_align_of_type (type);
|
||||
tree context = DECL_CONTEXT (field);
|
||||
unsigned int record_align = TYPE_ALIGN (context);
|
||||
if ((record_align % type_align) != 0)
|
||||
unsigned int record_align = min_align_of_type (context);
|
||||
if (record_align < type_align)
|
||||
return context;
|
||||
tree field_off = byte_position (field);
|
||||
if (!multiple_of_p (TREE_TYPE (field_off), field_off,
|
||||
size_int (type_align / BITS_PER_UNIT)))
|
||||
size_int (type_align)))
|
||||
return context;
|
||||
}
|
||||
|
||||
@ -2722,19 +2724,27 @@ check_alignment_of_packed_member (tree type, tree field)
|
||||
static tree
|
||||
check_address_or_pointer_of_packed_member (tree type, tree rhs)
|
||||
{
|
||||
bool rvalue = true;
|
||||
|
||||
if (INDIRECT_REF_P (rhs))
|
||||
rhs = TREE_OPERAND (rhs, 0);
|
||||
|
||||
if (TREE_CODE (rhs) == ADDR_EXPR)
|
||||
rhs = TREE_OPERAND (rhs, 0);
|
||||
{
|
||||
rhs = TREE_OPERAND (rhs, 0);
|
||||
rvalue = false;
|
||||
}
|
||||
|
||||
if (POINTER_TYPE_P (type))
|
||||
type = TREE_TYPE (type);
|
||||
if (!POINTER_TYPE_P (type))
|
||||
return NULL_TREE;
|
||||
|
||||
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. */
|
||||
@ -2742,24 +2752,30 @@ check_address_or_pointer_of_packed_member (tree type, tree rhs)
|
||||
return NULL_TREE;
|
||||
rhs = TREE_TYPE (rhs); /* Pointer type. */
|
||||
rhs = TREE_TYPE (rhs); /* Function type. */
|
||||
rhstype = TREE_TYPE (rhs);
|
||||
if (!POINTER_TYPE_P (rhstype))
|
||||
return NULL_TREE;
|
||||
rvalue = true;
|
||||
}
|
||||
tree rhstype = TREE_TYPE (rhs);
|
||||
if ((POINTER_TYPE_P (rhstype)
|
||||
|| TREE_CODE (rhstype) == ARRAY_TYPE)
|
||||
&& TYPE_PACKED (TREE_TYPE (rhstype)))
|
||||
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 = TYPE_ALIGN_UNIT (type);
|
||||
unsigned int rhs_align = TYPE_ALIGN_UNIT (TREE_TYPE (rhstype));
|
||||
if ((rhs_align % type_align) != 0)
|
||||
unsigned int type_align = min_align_of_type (type);
|
||||
unsigned int rhs_align = min_align_of_type (rhstype);
|
||||
if (rhs_align < type_align)
|
||||
{
|
||||
location_t location = EXPR_LOC_OR_LOC (rhs, input_location);
|
||||
warning_at (location, OPT_Waddress_of_packed_member,
|
||||
"converting a packed %qT pointer (alignment %d) "
|
||||
"to %qT (alignment %d) may result in an "
|
||||
"to a %qT pointer (alignment %d) may result in an "
|
||||
"unaligned pointer value",
|
||||
rhstype, rhs_align, type, type_align);
|
||||
tree decl = TYPE_STUB_DECL (TREE_TYPE (rhstype));
|
||||
inform (DECL_SOURCE_LOCATION (decl), "defined here");
|
||||
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");
|
||||
@ -2776,7 +2792,7 @@ check_address_or_pointer_of_packed_member (tree type, tree rhs)
|
||||
if (TREE_CODE (rhs) == COMPONENT_REF)
|
||||
{
|
||||
tree field = TREE_OPERAND (rhs, 1);
|
||||
context = check_alignment_of_packed_member (type, field);
|
||||
context = check_alignment_of_packed_member (type, field, rvalue);
|
||||
if (context)
|
||||
break;
|
||||
}
|
||||
|
@ -1,3 +1,9 @@
|
||||
2019-01-21 Bernd Edlinger <bernd.edlinger@hotmail.de>
|
||||
|
||||
PR c/88928
|
||||
* c-c++-common/Waddress-of-packed-member-1.c: New test case.
|
||||
* gcc.dg/pr88928.c: New test case.
|
||||
|
||||
2019-01-21 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* gcc.dg/utf-array.c: Allow wchar_t to be printed as
|
||||
|
55
gcc/testsuite/c-c++-common/Waddress-of-packed-member-1.c
Normal file
55
gcc/testsuite/c-c++-common/Waddress-of-packed-member-1.c
Normal file
@ -0,0 +1,55 @@
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-Waddress-of-packed-member" } */
|
||||
|
||||
struct t {
|
||||
char a;
|
||||
int b;
|
||||
int *c;
|
||||
int d[10];
|
||||
} __attribute__((packed));
|
||||
|
||||
struct t t0;
|
||||
struct t t10[10];
|
||||
struct t t100[10][10];
|
||||
struct t *t1;
|
||||
struct t **t2;
|
||||
struct t *bar();
|
||||
struct t (*baz())[10];
|
||||
struct t (*bazz())[10][10];
|
||||
int *i1;
|
||||
__UINTPTR_TYPE__ u1;
|
||||
__UINTPTR_TYPE__ baa();
|
||||
|
||||
void foo (void)
|
||||
{
|
||||
t1 = &t0; /* { dg-bogus "may result in an unaligned pointer value" } */
|
||||
t1 = t10; /* { dg-bogus "may result in an unaligned pointer value" } */
|
||||
t2 = &t1; /* { dg-bogus "may result in an unaligned pointer value" } */
|
||||
t2 = t2; /* { dg-bogus "may result in an unaligned pointer value" } */
|
||||
t2 = (struct t**)t2; /* { dg-bogus "may result in an unaligned pointer value" } */
|
||||
t1 = (struct t*)t2; /* { dg-bogus "may result in an unaligned pointer value" } */
|
||||
t1 = bar(); /* { dg-bogus "may result in an unaligned pointer value" } */
|
||||
t1 = (struct t*) baz(); /* { dg-bogus "may result in an unaligned pointer value" } */
|
||||
t1 = (struct t*) bazz(); /* { dg-bogus "may result in an unaligned pointer value" } */
|
||||
t1 = *baz(); /* { dg-bogus "may result in an unaligned pointer value" } */
|
||||
t1 = **bazz(); /* { dg-bogus "may result in an unaligned pointer value" } */
|
||||
t1 = (struct t*) baa(); /* { dg-bogus "may result in an unaligned pointer value" } */
|
||||
t2 = (struct t**) baa(); /* { dg-bogus "may result in an unaligned pointer value" } */
|
||||
i1 = t0.c; /* { dg-bogus "may result in an unaligned pointer value" } */
|
||||
i1 = t1->c; /* { dg-bogus "may result in an unaligned pointer value" } */
|
||||
i1 = t10[0].c; /* { dg-bogus "may result in an unaligned pointer value" } */
|
||||
u1 = (__UINTPTR_TYPE__) &t0; /* { dg-bogus "may result in an unaligned pointer value" } */
|
||||
u1 = (__UINTPTR_TYPE__) t1; /* { dg-bogus "may result in an unaligned pointer value" } */
|
||||
t2 = (struct t**) t10; /* { dg-warning "may result in an unaligned pointer value" } */
|
||||
t2 = (struct t**) t100; /* { dg-warning "may result in an unaligned pointer value" } */
|
||||
t2 = (struct t**) t1; /* { dg-warning "may result in an unaligned pointer value" } */
|
||||
t2 = (struct t**) bar(); /* { dg-warning "may result in an unaligned pointer value" } */
|
||||
t2 = (struct t**) baz(); /* { dg-warning "may result in an unaligned pointer value" } */
|
||||
t2 = (struct t**) bazz(); /* { dg-warning "may result in an unaligned pointer value" } */
|
||||
i1 = &t0.b; /* { dg-warning "may result in an unaligned pointer value" } */
|
||||
i1 = &t1->b; /* { dg-warning "may result in an unaligned pointer value" } */
|
||||
i1 = &t10[0].b; /* { dg-warning "may result in an unaligned pointer value" } */
|
||||
i1 = t0.d; /* { dg-warning "may result in an unaligned pointer value" } */
|
||||
i1 = t1->d; /* { dg-warning "may result in an unaligned pointer value" } */
|
||||
i1 = t10[0].d; /* { dg-warning "may result in an unaligned pointer value" } */
|
||||
}
|
6
gcc/testsuite/gcc.dg/pr88928.c
Normal file
6
gcc/testsuite/gcc.dg/pr88928.c
Normal file
@ -0,0 +1,6 @@
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-Wno-pedantic -Waddress-of-packed-member" } */
|
||||
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 *-*-* } .-1 } */
|
Loading…
Reference in New Issue
Block a user