C/C++: Add -Waddress-of-packed-member

When address of packed member of struct or union is taken, it may result
in an unaligned pointer value.  This patch adds -Waddress-of-packed-member
to check alignment at pointer assignment and warn unaligned address as
well as unaligned pointer:

$ cat x.i
struct pair_t
{
  char c;
  int i;
} __attribute__ ((packed));

extern struct pair_t p;
int *addr = &p.i;
$ gcc -O2 -S x.i
x.i:8:13: warning: taking address of packed member of ‘struct pair_t’ may result in an unaligned pointer value [-Waddress-of-packed-member]
8 | int *addr = &p.i;
  |             ^

$ cat c.i
struct B { int i; };
struct C { struct B b; } __attribute__ ((packed));

long* g8 (struct C *p) { return p; }
$ gcc -O2 -S c.i -Wno-incompatible-pointer-types
c.i: In function ‘g8’:
c.i:4:18: warning: converting a packed ‘struct C *’ pointer (alignment 1) to ‘long int *’ (alignment 8) may may result in an unaligned pointer value [-Waddress-of-packed-member]
4 | long* g8 (struct C *p) { return p; }
  |                  ^
c.i:2:8: note: defined here
2 | struct C { struct B b; } __attribute__ ((packed));
  |        ^
$

This warning is enabled by default.  Since read_encoded_value_with_base
in unwind-pe.h has

  union unaligned
    {
      void *ptr;
      unsigned u2 __attribute__ ((mode (HI)));
      unsigned u4 __attribute__ ((mode (SI)));
      unsigned u8 __attribute__ ((mode (DI)));
      signed s2 __attribute__ ((mode (HI)));
      signed s4 __attribute__ ((mode (SI)));
      signed s8 __attribute__ ((mode (DI)));
    } __attribute__((__packed__));
  _Unwind_Internal_Ptr result;

and GCC warns:

gcc/libgcc/unwind-pe.h:210:37: warning: taking address of packed member of 'union unaligned' may result in an unaligned pointer value [-Waddress-of-packed-member]
    result = (_Unwind_Internal_Ptr) u->ptr;
                                    ^
we need to add GCC pragma to ignore -Waddress-of-packed-member.

gcc/

	PR c/51628
	* doc/invoke.texi: Document -Wno-address-of-packed-member.

gcc/c-family/

	PR c/51628
	* c-common.h (warn_for_address_or_pointer_of_packed_member): New.
	* c-warn.c (check_alignment_of_packed_member): New function.
	(check_address_of_packed_member): Likewise.
	(check_and_warn_address_of_packed_member): Likewise.
	(warn_for_address_or_pointer_of_packed_member): Likewise.
	* c.opt: Add -Wno-address-of-packed-member.

gcc/c/

	PR c/51628
	* c-typeck.c (convert_for_assignment): Call
	warn_for_address_or_pointer_of_packed_member.

gcc/cp/

	PR c/51628
	* call.c (convert_for_arg_passing): Call
	warn_for_address_or_pointer_of_packed_member.
	* typeck.c (convert_for_assignment): Likewise.

gcc/testsuite/

	PR c/51628
	* c-c++-common/pr51628-1.c: New test.
	* c-c++-common/pr51628-2.c: Likewise.
	* c-c++-common/pr51628-3.c: Likewise.
	* c-c++-common/pr51628-4.c: Likewise.
	* c-c++-common/pr51628-5.c: Likewise.
	* c-c++-common/pr51628-6.c: Likewise.
	* c-c++-common/pr51628-7.c: Likewise.
	* c-c++-common/pr51628-8.c: Likewise.
	* c-c++-common/pr51628-9.c: Likewise.
	* c-c++-common/pr51628-10.c: Likewise.
	* c-c++-common/pr51628-11.c: Likewise.
	* c-c++-common/pr51628-12.c: Likewise.
	* c-c++-common/pr51628-13.c: Likewise.
	* c-c++-common/pr51628-14.c: Likewise.
	* c-c++-common/pr51628-15.c: Likewise.
	* c-c++-common/pr51628-26.c: Likewise.
	* c-c++-common/pr51628-27.c: Likewise.
	* c-c++-common/pr51628-28.c: Likewise.
	* c-c++-common/pr51628-29.c: Likewise.
	* c-c++-common/pr51628-30.c: Likewise.
	* c-c++-common/pr51628-31.c: Likewise.
	* c-c++-common/pr51628-32.c: Likewise.
	* gcc.dg/pr51628-17.c: Likewise.
	* gcc.dg/pr51628-18.c: Likewise.
	* gcc.dg/pr51628-19.c: Likewise.
	* gcc.dg/pr51628-20.c: Likewise.
	* gcc.dg/pr51628-21.c: Likewise.
	* gcc.dg/pr51628-22.c: Likewise.
	* gcc.dg/pr51628-23.c: Likewise.
	* gcc.dg/pr51628-24.c: Likewise.
	* gcc.dg/pr51628-25.c: Likewise.
	* c-c++-common/asan/misalign-1.c: Add
	-Wno-address-of-packed-member.
	* c-c++-common/asan/misalign-2.c: Likewise.
	* c-c++-common/ubsan/align-2.c: Likewise.
	* c-c++-common/ubsan/align-4.c: Likewise.
	* c-c++-common/ubsan/align-6.c: Likewise.
	* c-c++-common/ubsan/align-7.c: Likewise.
	* c-c++-common/ubsan/align-8.c: Likewise.
	* c-c++-common/ubsan/align-10.c: Likewise.
	* g++.dg/ubsan/align-2.C: Likewise.
	* gcc.target/i386/avx512bw-vmovdqu16-2.c: Likewise.
	* gcc.target/i386/avx512f-vmovdqu32-2.c: Likewise.
	* gcc.target/i386/avx512f-vmovdqu64-2.c: Likewise.
	* gcc.target/i386/avx512vl-vmovdqu16-2.c: Likewise.
	* gcc.target/i386/avx512vl-vmovdqu32-2.c: Likewise.
	* gcc.target/i386/avx512vl-vmovdqu64-2.c: Likewise.

libgcc/

	* unwind-pe.h (read_encoded_value_with_base): Add GCC pragma
	to ignore -Waddress-of-packed-member.

From-SVN: r267313
This commit is contained in:
H.J. Lu 2018-12-20 21:41:48 +00:00 committed by H.J. Lu
parent 11e07fa432
commit da77eace90
61 changed files with 970 additions and 19 deletions

View File

@ -1,3 +1,8 @@
2018-12-20 H.J. Lu <hongjiu.lu@intel.com>
PR c/51628
* doc/invoke.texi: Document -Wno-address-of-packed-member.
2018-12-20 Vladimir Makarov <vmakarov@redhat.com>
PR target/88457

View File

@ -1,3 +1,13 @@
2018-12-20 H.J. Lu <hongjiu.lu@intel.com>
PR c/51628
* c-common.h (warn_for_address_or_pointer_of_packed_member): New.
* c-warn.c (check_alignment_of_packed_member): New function.
(check_address_of_packed_member): Likewise.
(check_and_warn_address_of_packed_member): Likewise.
(warn_for_address_or_pointer_of_packed_member): Likewise.
* c.opt: Add -Wno-address-of-packed-member.
2018-12-20 David Malcolm <dmalcolm@redhat.com>
PR c++/87504

View File

@ -1283,6 +1283,7 @@ extern void c_do_switch_warnings (splay_tree, location_t, tree, tree, bool,
bool);
extern void warn_for_omitted_condop (location_t, tree);
extern bool warn_for_restrict (unsigned, tree *, unsigned);
extern void warn_for_address_or_pointer_of_packed_member (bool, tree, tree);
/* Places where an lvalue, or modifiable lvalue, may be required.
Used to select diagnostic messages in lvalue_error and

View File

@ -2686,3 +2686,167 @@ warn_for_multistatement_macros (location_t body_loc, location_t next_loc,
inform (guard_loc, "some parts of macro expansion are not guarded by "
"this %qs clause", guard_tinfo_to_string (keyword));
}
/* Return struct or union type if the alignment of data memeber, FIELD,
is less than the alignment of TYPE. Otherwise, return NULL_TREE. */
static tree
check_alignment_of_packed_member (tree type, tree field)
{
/* Check alignment of the data member. */
if (TREE_CODE (field) == FIELD_DECL
&& (DECL_PACKED (field)
|| TYPE_PACKED (TREE_TYPE (field))))
{
/* Check the expected alignment against the field alignment. */
unsigned int type_align = TYPE_ALIGN (type);
tree context = DECL_CONTEXT (field);
unsigned int record_align = TYPE_ALIGN (context);
if ((record_align % type_align) != 0)
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)))
return context;
}
return NULL_TREE;
}
/* Return struct or union type if the right hand value, RHS, takes the
unaligned address of packed member of struct or union when assigning
to TYPE. Otherwise, return NULL_TREE. */
static tree
check_address_of_packed_member (tree type, tree rhs)
{
if (INDIRECT_REF_P (rhs))
rhs = TREE_OPERAND (rhs, 0);
if (TREE_CODE (rhs) == ADDR_EXPR)
rhs = TREE_OPERAND (rhs, 0);
tree context = NULL_TREE;
/* Check alignment of the object. */
while (handled_component_p (rhs))
{
if (TREE_CODE (rhs) == COMPONENT_REF)
{
tree field = TREE_OPERAND (rhs, 1);
context = check_alignment_of_packed_member (type, field);
if (context)
break;
}
rhs = TREE_OPERAND (rhs, 0);
}
return context;
}
/* Check and warn if the right hand value, RHS, takes the unaligned
address of packed member of struct or union when assigning to TYPE. */
static void
check_and_warn_address_of_packed_member (tree type, tree rhs)
{
if (TREE_CODE (rhs) != COND_EXPR)
{
while (TREE_CODE (rhs) == COMPOUND_EXPR)
rhs = TREE_OPERAND (rhs, 1);
tree context = check_address_of_packed_member (type, rhs);
if (context)
{
location_t loc = EXPR_LOC_OR_LOC (rhs, input_location);
warning_at (loc, OPT_Waddress_of_packed_member,
"taking address of packed member of %qT may result "
"in an unaligned pointer value",
context);
}
return;
}
/* Check the THEN path. */
check_and_warn_address_of_packed_member (type, TREE_OPERAND (rhs, 1));
/* Check the ELSE path. */
check_and_warn_address_of_packed_member (type, TREE_OPERAND (rhs, 2));
}
/* Warn if the right hand value, RHS:
1. For CONVERT_P == true, is a pointer value which isn't aligned to a
pointer type TYPE.
2. For CONVERT_P == false, is an address which takes the unaligned
address of packed member of struct or union when assigning to TYPE.
*/
void
warn_for_address_or_pointer_of_packed_member (bool convert_p, tree type,
tree rhs)
{
if (!warn_address_of_packed_member)
return;
/* Don't warn if we don't assign RHS to a pointer. */
if (!POINTER_TYPE_P (type))
return;
while (TREE_CODE (rhs) == COMPOUND_EXPR)
rhs = TREE_OPERAND (rhs, 1);
if (convert_p)
{
bool rhspointer_p;
tree rhstype;
/* Check the original type of RHS. */
switch (TREE_CODE (rhs))
{
case PARM_DECL:
case VAR_DECL:
rhstype = TREE_TYPE (rhs);
rhspointer_p = POINTER_TYPE_P (rhstype);
break;
case NOP_EXPR:
rhs = TREE_OPERAND (rhs, 0);
if (TREE_CODE (rhs) == ADDR_EXPR)
rhs = TREE_OPERAND (rhs, 0);
rhstype = TREE_TYPE (rhs);
rhspointer_p = TREE_CODE (rhstype) == ARRAY_TYPE;
break;
default:
return;
}
if (rhspointer_p && TYPE_PACKED (TREE_TYPE (rhstype)))
{
unsigned int type_align = TYPE_ALIGN_UNIT (TREE_TYPE (type));
unsigned int rhs_align = TYPE_ALIGN_UNIT (TREE_TYPE (rhstype));
if ((rhs_align % type_align) != 0)
{
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 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");
decl = TYPE_STUB_DECL (TREE_TYPE (type));
if (decl)
inform (DECL_SOURCE_LOCATION (decl), "defined here");
}
}
}
else
{
/* Get the type of the pointer pointing to. */
type = TREE_TYPE (type);
if (TREE_CODE (rhs) == NOP_EXPR)
rhs = TREE_OPERAND (rhs, 0);
check_and_warn_address_of_packed_member (type, rhs);
}
}

View File

@ -625,6 +625,10 @@ Wincompatible-pointer-types
C ObjC Var(warn_incompatible_pointer_types) Init(1) Warning
Warn when there is a conversion between pointers that have incompatible types.
Waddress-of-packed-member
C ObjC C++ ObjC++ Var(warn_address_of_packed_member) Init(1) Warning
Warn when the address of packed member of struct or union is taken.
Winit-self
C ObjC C++ ObjC++ Var(warn_init_self) Warning LangEnabledBy(C++ ObjC++,Wall)
Warn about variables which are initialized to themselves.

View File

@ -1,3 +1,9 @@
2018-12-20 H.J. Lu <hongjiu.lu@intel.com>
PR c/51628
* c-typeck.c (convert_for_assignment): Call
warn_for_address_or_pointer_of_packed_member.
2018-12-19 Segher Boessenkool <segher@kernel.crashing.org>
* c-parser.c (c_parser_asm_statement) <RID_CONST, RID_RESTRICT>: Give

View File

@ -6724,7 +6724,11 @@ convert_for_assignment (location_t location, location_t expr_loc, tree type,
}
if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (rhstype))
return rhs;
{
warn_for_address_or_pointer_of_packed_member (false, type,
orig_rhs);
return rhs;
}
if (coder == VOID_TYPE)
{
@ -7279,6 +7283,11 @@ convert_for_assignment (location_t location, location_t expr_loc, tree type,
}
}
/* If RHS is't an address, check pointer or array of packed
struct or union. */
warn_for_address_or_pointer_of_packed_member
(TREE_CODE (orig_rhs) != ADDR_EXPR, type, orig_rhs);
return convert (type, rhs);
}
else if (codel == POINTER_TYPE && coder == ARRAY_TYPE)

View File

@ -1,3 +1,10 @@
2018-12-20 H.J. Lu <hongjiu.lu@intel.com>
PR c/51628
* call.c (convert_for_arg_passing): Call
warn_for_address_or_pointer_of_packed_member.
* typeck.c (convert_for_assignment): Likewise.
2018-12-20 Jakub Jelinek <jakub@redhat.com>
PR c++/88180

View File

@ -7629,6 +7629,9 @@ convert_for_arg_passing (tree type, tree val, tsubst_flags_t complain)
}
maybe_warn_parm_abi (type, cp_expr_loc_or_loc (val, input_location));
}
warn_for_address_or_pointer_of_packed_member (false, type, val);
return val;
}

View File

@ -9073,6 +9073,8 @@ convert_for_assignment (tree type, tree rhs,
TREE_NO_WARNING (rhs) = 1;
}
warn_for_address_or_pointer_of_packed_member (false, type, rhs);
return perform_implicit_conversion_flags (strip_top_quals (type), rhs,
complain, flags);
}

View File

@ -281,7 +281,8 @@ Objective-C and Objective-C++ Dialects}.
@xref{Warning Options,,Options to Request or Suppress Warnings}.
@gccoptlist{-fsyntax-only -fmax-errors=@var{n} -Wpedantic @gol
-pedantic-errors @gol
-w -Wextra -Wall -Waddress -Waggregate-return -Waligned-new @gol
-w -Wextra -Wall -Waddress -Waddress-of-packed-member @gol
-Waggregate-return -Waligned-new @gol
-Walloc-zero -Walloc-size-larger-than=@var{byte-size} @gol
-Walloca -Walloca-larger-than=@var{byte-size} @gol
-Wno-aggressive-loop-optimizations -Warray-bounds -Warray-bounds=@var{n} @gol
@ -310,7 +311,7 @@ Objective-C and Objective-C++ Dialects}.
-Wformat-y2k -Wframe-address @gol
-Wframe-larger-than=@var{byte-size} -Wno-free-nonheap-object @gol
-Wjump-misses-init @gol
-Wif-not-aligned @gol
-Whsa -Wif-not-aligned @gol
-Wignored-qualifiers -Wignored-attributes -Wincompatible-pointer-types @gol
-Wimplicit -Wimplicit-fallthrough -Wimplicit-fallthrough=@var{n} @gol
-Wimplicit-function-declaration -Wimplicit-int @gol
@ -358,7 +359,7 @@ Objective-C and Objective-C++ Dialects}.
-Wuseless-cast -Wvariadic-macros -Wvector-operation-performance @gol
-Wvla -Wvla-larger-than=@var{byte-size} -Wvolatile-register-var @gol
-Wwrite-strings @gol
-Wzero-as-null-pointer-constant -Whsa}
-Wzero-as-null-pointer-constant}
@item C and Objective-C-only Warning Options
@gccoptlist{-Wbad-function-cast -Wmissing-declarations @gol
@ -6981,6 +6982,13 @@ behavior and are not portable in C, so they usually indicate that the
programmer intended to use @code{strcmp}. This warning is enabled by
@option{-Wall}.
@item -Waddress-of-packed-member
@opindex Waddress-of-packed-member
@opindex Wno-address-of-packed-member
Warn when the address of packed member of struct or union is taken,
which usually results in an unaligned pointer value. This is
enabled by default.
@item -Wlogical-op
@opindex Wlogical-op
@opindex Wno-logical-op

View File

@ -1,3 +1,54 @@
2018-12-20 H.J. Lu <hongjiu.lu@intel.com>
PR c/51628
* c-c++-common/pr51628-1.c: New test.
* c-c++-common/pr51628-2.c: Likewise.
* c-c++-common/pr51628-3.c: Likewise.
* c-c++-common/pr51628-4.c: Likewise.
* c-c++-common/pr51628-5.c: Likewise.
* c-c++-common/pr51628-6.c: Likewise.
* c-c++-common/pr51628-7.c: Likewise.
* c-c++-common/pr51628-8.c: Likewise.
* c-c++-common/pr51628-9.c: Likewise.
* c-c++-common/pr51628-10.c: Likewise.
* c-c++-common/pr51628-11.c: Likewise.
* c-c++-common/pr51628-12.c: Likewise.
* c-c++-common/pr51628-13.c: Likewise.
* c-c++-common/pr51628-14.c: Likewise.
* c-c++-common/pr51628-15.c: Likewise.
* c-c++-common/pr51628-26.c: Likewise.
* c-c++-common/pr51628-27.c: Likewise.
* c-c++-common/pr51628-28.c: Likewise.
* c-c++-common/pr51628-29.c: Likewise.
* c-c++-common/pr51628-30.c: Likewise.
* c-c++-common/pr51628-31.c: Likewise.
* c-c++-common/pr51628-32.c: Likewise.
* gcc.dg/pr51628-17.c: Likewise.
* gcc.dg/pr51628-18.c: Likewise.
* gcc.dg/pr51628-19.c: Likewise.
* gcc.dg/pr51628-20.c: Likewise.
* gcc.dg/pr51628-21.c: Likewise.
* gcc.dg/pr51628-22.c: Likewise.
* gcc.dg/pr51628-23.c: Likewise.
* gcc.dg/pr51628-24.c: Likewise.
* gcc.dg/pr51628-25.c: Likewise.
* c-c++-common/asan/misalign-1.c: Add
-Wno-address-of-packed-member.
* c-c++-common/asan/misalign-2.c: Likewise.
* c-c++-common/ubsan/align-2.c: Likewise.
* c-c++-common/ubsan/align-4.c: Likewise.
* c-c++-common/ubsan/align-6.c: Likewise.
* c-c++-common/ubsan/align-7.c: Likewise.
* c-c++-common/ubsan/align-8.c: Likewise.
* c-c++-common/ubsan/align-10.c: Likewise.
* g++.dg/ubsan/align-2.C: Likewise.
* gcc.target/i386/avx512bw-vmovdqu16-2.c: Likewise.
* gcc.target/i386/avx512f-vmovdqu32-2.c: Likewise.
* gcc.target/i386/avx512f-vmovdqu64-2.c: Likewise.
* gcc.target/i386/avx512vl-vmovdqu16-2.c: Likewise.
* gcc.target/i386/avx512vl-vmovdqu32-2.c: Likewise.
* gcc.target/i386/avx512vl-vmovdqu64-2.c: Likewise.
2018-12-20 Vladimir Makarov <vmakarov@redhat.com>
PR target/88457

View File

@ -1,5 +1,5 @@
/* { dg-do run { target { ilp32 || lp64 } } } */
/* { dg-skip-if "" { *-*-* } { "*" } { "-O2" } } */
/* { dg-skip-if "" { *-*-* } { "*" } { "-O2 -Wno-address-of-packed-member" } } */
/* { dg-additional-options "-fno-omit-frame-pointer" { target *-*-darwin* } } */
/* { dg-shouldfail "asan" } */

View File

@ -1,5 +1,5 @@
/* { dg-do run { target { ilp32 || lp64 } } } */
/* { dg-skip-if "" { *-*-* } { "*" } { "-O2" } } */
/* { dg-skip-if "" { *-*-* } { "*" } { "-O2 -Wno-address-of-packed-member" } } */
/* { dg-additional-options "-fno-omit-frame-pointer" { target *-*-darwin* } } */
/* { dg-shouldfail "asan" } */

View File

@ -0,0 +1,29 @@
/* PR c/51628. */
/* { dg-do compile } */
/* { dg-options "-O" } */
struct pair_t
{
int x;
int i;
} __attribute__((packed, aligned (4)));
extern struct pair_t p;
extern int *x;
extern void bar (int *);
int *addr = &p.i;
int *
foo (void)
{
struct pair_t arr[2] = { { 1, 10 }, { 2, 20 } };
int *p0, *p1;
p0 = &arr[0].i;
bar (p0);
p1 = &arr[1].i;
bar (p1);
bar (&p.i);
x = &p.i;
return &p.i;
}

View File

@ -0,0 +1,24 @@
/* PR c/51628. */
/* { dg-do run { target int128 } } */
/* { dg-options "-O2" } */
struct pair_t
{
char c;
__int128_t i;
} __attribute__ ((packed));
typedef struct unaligned_int128_t_
{
__int128_t value;
} __attribute__((packed)) unaligned_int128_t;
struct pair_t p = {0, 1};
unaligned_int128_t *addr = (unaligned_int128_t *) &p.i;
int
main()
{
addr->value = ~(__int128_t)0;
return (p.i != 1) ? 0 : 1;
}

View File

@ -0,0 +1,17 @@
/* PR c/51628. */
/* { dg-do compile { target int128 } } */
/* { dg-options "-O" } */
struct tuple_t
{
char c[12];
__int128_t i;
} __attribute__((packed, aligned (8)));
typedef struct unaligned_int128_t_
{
__int128_t value;
} __attribute__ ((packed, aligned(4))) unaligned_int128_t;
struct tuple_t p = {{0}, 1};
unaligned_int128_t *addr = (unaligned_int128_t *)(&p.i);

View File

@ -0,0 +1,18 @@
/* PR c/51628. */
/* { dg-do compile { target int128 } } */
/* { dg-options "-O" } */
struct tuple_t
{
char c[10];
__int128_t i;
} __attribute__((packed, aligned (8)));
typedef struct unaligned_int128_t_
{
__int128_t value;
} __attribute__ ((packed, aligned(4))) unaligned_int128_t;
struct tuple_t p = {{0}, 1};
unaligned_int128_t *addr = (unaligned_int128_t *)(&p.i);
/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */

View File

@ -0,0 +1,9 @@
/* PR c/51628. */
/* { dg-do compile } */
/* { dg-options "-O" } */
struct B { int i; };
struct C { struct B b; } __attribute__ ((packed));
int* h4 (struct C *p) { return &p->b.i; }
/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */

View File

@ -0,0 +1,9 @@
/* PR c/51628. */
/* { dg-do compile } */
/* { dg-options "-O" } */
struct A {
int i;
} __attribute__ ((packed));
void* f0 (struct A *p) { return &p->i; }

View File

@ -0,0 +1,14 @@
/* PR c/51628. */
/* { dg-do compile } */
/* { dg-options "-O" } */
struct A {
int i;
} __attribute__ ((packed));
int*
f (struct A *p, int *q)
{
return q ? q : &p->i;
/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
}

View File

@ -0,0 +1,13 @@
/* PR c/51628. */
/* { dg-do compile } */
/* { dg-options "-O" } */
struct __attribute__ ((packed)) A { int i; };
struct B {
struct A a;
} b;
int *p = (int*)&b.a.i;
/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
int *q = (int*)&b.a;
/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */

View File

@ -0,0 +1,29 @@
/* PR c/51628. */
/* { dg-do compile } */
/* { dg-options "-O" } */
struct pair_t
{
int x;
int i;
} __attribute__((packed, aligned (8)));
extern struct pair_t p;
extern int *x;
extern void bar (int *);
int *addr = &p.i;
int *
foo (void)
{
struct pair_t arr[2] = { { 1, 10 }, { 2, 20 } };
int *p0, *p1;
p0 = &arr[0].i;
bar (p0);
p1 = &arr[1].i;
bar (p1);
bar (&p.i);
x = &p.i;
return &p.i;
}

View File

@ -0,0 +1,33 @@
/* PR c/51628. */
/* { dg-do compile } */
/* { dg-options "-O" } */
struct A {
int i;
} __attribute__ ((packed));
struct A p = {1};
int *addr;
int i, j;
void
foo1 (void)
{
addr = (i = -1, &p.i);
/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
}
void
foo2 (void)
{
addr = (i = -1, j = -2, &p.i);
/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
}
void
foo3 (void)
{
addr = (i = -1, (j = -2, &p.i));
/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
}

View File

@ -0,0 +1,12 @@
/* PR c/51628. */
/* { dg-do compile } */
/* { dg-options "-O" } */
struct A { int i; } __attribute__ ((packed));
struct B { struct A a; };
struct C { struct B b; };
extern struct C *p;
int* g8 (void) { return &p->b.a.i; }
/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */

View File

@ -0,0 +1,31 @@
/* PR c/51628. */
/* { dg-do compile } */
/* { dg-options "-O" } */
struct A {
int i;
} __attribute__ ((packed));
int *
foo3 (struct A *p1, int *q1, int *q2, struct A *p2)
{
return (q1
? &p1->i
/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
: (q2 ? &p2->i : q2));
/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
}
int*
foo4 (struct A *p1, int **q1, int *q2, int *q3, struct A *p2)
{
return (q1
? (*q1 = q2, &p1->i)
/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
: (q2
? (*q1 = &p1->i,
/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
*q2 = 2, &p2->i)
/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
: q2));
}

View File

@ -0,0 +1,16 @@
/* PR c/51628. */
/* { dg-do compile } */
/* { dg-options "-O" } */
struct A { int i; };
struct B { struct A a; };
struct C { struct B b __attribute__ ((packed)); };
extern struct C *p;
int*
g8 (void)
{
return &p->b.a.i;
/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
}

View File

@ -0,0 +1,35 @@
/* PR c/51628. */
/* { dg-do compile } */
/* { dg-options "-O" } */
struct pair_t
{
int x;
int i;
} __attribute__((packed, aligned (2)));
extern struct pair_t p;
extern int *x;
extern void bar (int *);
int *addr = &p.i;
/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
int *
foo (void)
{
struct pair_t arr[2] = { { 1, 10 }, { 2, 20 } };
int *p0, *p1;
p0 = &arr[0].i;
/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
bar (p0);
p1 = &arr[1].i;
/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
bar (p1);
bar (&p.i);
/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
x = &p.i;
/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
return &p.i;
/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
}

View File

@ -0,0 +1,23 @@
/* PR c/51628. */
/* { dg-do compile } */
/* { dg-options "-O" } */
struct A { __complex int i; };
struct B { struct A a; };
struct C { struct B b __attribute__ ((packed)); };
extern struct C *p;
int*
foo1 (void)
{
return &__real(p->b.a.i);
/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
}
int*
foo2 (void)
{
return &__imag(p->b.a.i);
/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
}

View File

@ -0,0 +1,16 @@
/* PR c/51628. */
/* { dg-do compile } */
/* { dg-options "-O" } */
typedef int v4si __attribute__((vector_size(16)));
struct X
{
v4si x;
} __attribute__((packed)) x;
int *
foo()
{
return &x.x[1];
/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
}

View File

@ -0,0 +1,19 @@
/* PR c/51628. */
/* { dg-do compile } */
/* { dg-options "-O" } */
struct A
{
int i;
};
struct B
{
char c;
__attribute ((packed)) struct A ar[4];
};
struct B b;
int *p = &b.ar[1].i;
/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */

View File

@ -0,0 +1,35 @@
/* PR c/51628. */
/* { dg-do compile } */
/* { dg-options "-O" } */
struct pair_t
{
int x;
int i;
} __attribute__((packed));
extern struct pair_t p;
extern int *x;
extern void bar (int *);
int *addr = &p.i;
/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
int *
foo (void)
{
struct pair_t arr[2] = { { 1, 10 }, { 2, 20 } };
int *p0, *p1;
p0 = &arr[0].i;
/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
bar (p0);
p1 = &arr[1].i;
/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
bar (p1);
bar (&p.i);
/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
x = &p.i;
/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
return &p.i;
/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
}

View File

@ -0,0 +1,35 @@
/* PR c/51628. */
/* { dg-do compile } */
/* { dg-options "-O" } */
struct pair_t
{
char x;
int i;
} __attribute__((packed));
extern struct pair_t p;
extern int *x;
extern void bar (int *);
int *addr = &p.i;
/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
int *
foo (void)
{
struct pair_t arr[2] = { { 1, 10 }, { 2, 20 } };
int *p0, *p1;
p0 = &arr[0].i;
/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
bar (p0);
p1 = &arr[1].i;
/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
bar (p1);
bar (&p.i);
/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
x = &p.i;
/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
return &p.i;
/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
}

View File

@ -0,0 +1,35 @@
/* PR c/51628. */
/* { dg-do compile } */
/* { dg-options "-O" } */
struct pair_t
{
char x;
int i;
} __attribute__((packed, aligned (4)));
extern struct pair_t p;
extern int *x;
extern void bar (int *);
int *addr = &p.i;
/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
int *
foo (void)
{
struct pair_t arr[2] = { { 1, 10 }, { 2, 20 } };
int *p0, *p1;
p0 = &arr[0].i;
/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
bar (p0);
p1 = &arr[1].i;
/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
bar (p1);
bar (&p.i);
/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
x = &p.i;
/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
return &p.i;
/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
}

View File

@ -0,0 +1,29 @@
/* PR c/51628. */
/* { dg-do compile } */
/* { dg-options "-O" } */
struct pair_t
{
int x;
int i[4];
} __attribute__((packed, aligned (4)));
extern struct pair_t p;
extern int *x;
extern void bar (int *);
int *addr = p.i;
int *
foo (struct pair_t *p)
{
int *p0, *p1;
p0 = p->i;
bar (p0);
p1 = &p->i[1];
bar (p1);
bar (p->i);
bar (&p->i[2]);
x = p->i;
return &p->i[3];
}

View File

@ -0,0 +1,36 @@
/* PR c/51628. */
/* { dg-do compile } */
/* { dg-options "-O" } */
struct pair_t
{
char x;
int i[4];
} __attribute__ ((packed, aligned (4)));
extern struct pair_t p;
extern int *x;
extern void bar (int *);
int *addr = p.i;
/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
int *
foo (struct pair_t *p)
{
int *p0, *p1;
p0 = p->i;
/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
bar (p0);
p1 = &p->i[1];
/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
bar (p1);
bar (p->i);
/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
bar (&p->i[2]);
/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
x = p->i;
/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
return &p->i[3];
/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
}

View File

@ -0,0 +1,36 @@
/* PR c/51628. */
/* { dg-do compile } */
/* { dg-options "-O" } */
struct pair_t
{
int x;
int i[4];
} __attribute__ ((packed));
extern struct pair_t p;
extern int *x;
extern void bar (int *);
int *addr = p.i;
/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
int *
foo (struct pair_t *p)
{
int *p0, *p1;
p0 = p->i;
/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
bar (p0);
p1 = &p->i[1];
/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
bar (p1);
bar (p->i);
/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
bar (&p->i[2]);
/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
x = p->i;
/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
return &p->i[3];
/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
}

View File

@ -1,6 +1,6 @@
/* Limit this to known non-strict alignment targets. */
/* { dg-do run { target { i?86-*-linux* x86_64-*-linux* } } } */
/* { dg-options "-O -fsanitize=alignment -fsanitize-recover=alignment" } */
/* { dg-options "-O -fsanitize=alignment -fsanitize-recover=alignment -Wno-address-of-packed-member" } */
struct R { int a; } r;
struct S { struct R a; char b; long long c; short d[10]; };

View File

@ -1,6 +1,6 @@
/* Limit this to known non-strict alignment targets. */
/* { dg-do run { target { i?86-*-linux* x86_64-*-linux* } } } */
/* { dg-options "-fsanitize=alignment" } */
/* { dg-options "-fsanitize=alignment -Wno-address-of-packed-member" } */
struct S { int a; char b; long long c; short d[10]; };
struct T { char a; long long b; };

View File

@ -1,6 +1,6 @@
/* Limit this to known non-strict alignment targets. */
/* { dg-do run { target { i?86-*-linux* x86_64-*-linux* } } } */
/* { dg-options "-fsanitize=null,alignment" } */
/* { dg-options "-fsanitize=null,alignment -Wno-address-of-packed-member" } */
#include "align-2.c"

View File

@ -1,6 +1,6 @@
/* Limit this to known non-strict alignment targets. */
/* { dg-do run { target { i?86-*-linux* x86_64-*-linux* } } } */
/* { dg-options "-O -fsanitize=alignment -fsanitize-recover=alignment" } */
/* { dg-options "-O -fsanitize=alignment -fsanitize-recover=alignment -Wno-address-of-packed-member" } */
struct S { int a; char b; long long c; short d[10]; };
struct T { char a; long long b; };

View File

@ -1,6 +1,6 @@
/* Limit this to known non-strict alignment targets. */
/* { dg-do run { target { i?86-*-linux* x86_64-*-linux* } } } */
/* { dg-options "-O -fsanitize=alignment -fno-sanitize-recover=alignment -fdump-tree-sanopt-details" } */
/* { dg-options "-O -fsanitize=alignment -fno-sanitize-recover=alignment -Wno-address-of-packed-member -fdump-tree-sanopt-details" } */
/* { dg-skip-if "" { *-*-* } { "-flto -fno-fat-lto-objects" } } */
/* { dg-shouldfail "ubsan" } */

View File

@ -1,6 +1,6 @@
/* Limit this to known non-strict alignment targets. */
/* { dg-do run { target { i?86-*-linux* x86_64-*-linux* } } } */
/* { dg-options "-O -fsanitize=alignment -fsanitize-undefined-trap-on-error -fdump-tree-sanopt-details" } */
/* { dg-options "-O -fsanitize=alignment -fsanitize-undefined-trap-on-error -Wno-address-of-packed-member -fdump-tree-sanopt-details" } */
/* { dg-skip-if "" { *-*-* } { "-flto -fno-fat-lto-objects" } } */
/* { dg-shouldfail "ubsan" } */

View File

@ -1,6 +1,6 @@
// Limit this to known non-strict alignment targets.
// { dg-do run { target { i?86-*-linux* x86_64-*-linux* } } }
// { dg-options "-fsanitize=alignment -Wall -Wno-unused-variable -std=c++11" }
// { dg-options "-fsanitize=alignment -Wall -Wno-unused-variable -Wno-address-of-packed-member -std=c++11" }
typedef const long int L;
struct S { long int l; char buf[1 + sizeof (int) + sizeof (L)]; } s;

View File

@ -0,0 +1,10 @@
/* PR c/51628. */
/* { dg-do compile } */
/* { dg-options "-O -Wno-incompatible-pointer-types" } */
struct A {
int i;
} __attribute__ ((packed));
long* f8 (struct A *p) { return &p->i; }
/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */

View File

@ -0,0 +1,23 @@
/* PR c/51628. */
/* { dg-do compile } */
/* { dg-options "-O" } */
void foo (int *);
int *
bar (int n, int k, void *ptr)
{
struct A
{
int c[k];
int x[n];
} __attribute__ ((packed, aligned (4)));
struct A *p = (struct A *) ptr;
int *p0, *p1;
p0 = p->x;
foo (p0);
p1 = &p->x[1];
foo (p1);
return &p->x[1];
}

View File

@ -0,0 +1,26 @@
/* PR c/51628. */
/* { dg-do compile } */
/* { dg-options "-O" } */
void foo (int *);
int *
bar (int n, int k, void *ptr)
{
struct A
{
char c[k];
int x[n];
} __attribute__ ((packed));
struct A *p = (struct A *) ptr;
int *p0, *p1;
p0 = p->x;
/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
foo (p0);
p1 = &p->x[1];
/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
foo (p1);
return &p->x[1];
/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
}

View File

@ -0,0 +1,11 @@
/* 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 may result in an unaligned pointer value" "" { target *-*-* } .-1 } */

View File

@ -0,0 +1,11 @@
/* 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 may result in an unaligned pointer value" "" { target *-*-* } .-1 } */

View File

@ -0,0 +1,9 @@
/* PR c/51628. */
/* { dg-do compile } */
/* { dg-options "-O -Wno-incompatible-pointer-types" } */
struct B { int i; };
struct C { struct B b; } __attribute__ ((packed));
int* g4 (struct C *p) { return &p->b; }
/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */

View File

@ -0,0 +1,9 @@
/* PR c/51628. */
/* { dg-do compile } */
/* { dg-options "-O -Wno-incompatible-pointer-types" } */
struct A {
int i;
} __attribute__ ((packed));
char* f0 (struct A *p) { return &p->i; }

View File

@ -0,0 +1,10 @@
/* PR c/51628. */
/* { dg-do compile } */
/* { dg-options "-O -Wno-incompatible-pointer-types" } */
struct A {
int i;
} __attribute__ ((packed));
short* f2 (struct A *p) { return &p->i; }
/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */

View File

@ -0,0 +1,9 @@
/* 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 may result in an unaligned pointer value" "" { target *-*-* } .-1 } */

View File

@ -1,5 +1,5 @@
/* { dg-do run } */
/* { dg-options "-O2 -mavx512bw" } */
/* { dg-options "-O2 -mavx512bw -Wno-address-of-packed-member" } */
/* { dg-require-effective-target avx512bw } */
#define AVX512BW

View File

@ -1,5 +1,5 @@
/* { dg-do run } */
/* { dg-options "-O2 -mavx512f" } */
/* { dg-options "-O2 -mavx512f -Wno-address-of-packed-member" } */
/* { dg-require-effective-target avx512f } */
#define AVX512F

View File

@ -1,5 +1,5 @@
/* { dg-do run } */
/* { dg-options "-O2 -mavx512f" } */
/* { dg-options "-O2 -mavx512f -Wno-address-of-packed-member" } */
/* { dg-require-effective-target avx512f } */
#define AVX512F

View File

@ -1,5 +1,5 @@
/* { dg-do run } */
/* { dg-options "-O2 -mavx512bw -mavx512vl" } */
/* { dg-options "-O2 -mavx512bw -mavx512vl -Wno-address-of-packed-member" } */
/* { dg-require-effective-target avx512vl } */
/* { dg-require-effective-target avx512bw } */

View File

@ -1,5 +1,5 @@
/* { dg-do run } */
/* { dg-options "-O2 -mavx512vl" } */
/* { dg-options "-O2 -mavx512vl -Wno-address-of-packed-member" } */
/* { dg-require-effective-target avx512vl } */
#define AVX512VL

View File

@ -1,5 +1,5 @@
/* { dg-do run } */
/* { dg-options "-O2 -mavx512vl" } */
/* { dg-options "-O2 -mavx512vl -Wno-address-of-packed-member" } */
/* { dg-require-effective-target avx512vl } */
#define AVX512VL

View File

@ -1,3 +1,8 @@
2018-12-20 H.J. Lu <hongjiu.lu@intel.com>
* unwind-pe.h (read_encoded_value_with_base): Add GCC pragma
to ignore -Waddress-of-packed-member.
2018-12-19 Thomas Preud'homme <thomas.preudhomme@linaro.org>
* /config/arm/lib1funcs.S (FUNC_START): Remove unused sp_section

View File

@ -177,6 +177,9 @@ read_sleb128 (const unsigned char *p, _sleb128_t *val)
The function returns P incremented past the value. BASE is as given
by base_of_encoded_value for this encoding in the appropriate context. */
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Waddress-of-packed-member"
static const unsigned char *
read_encoded_value_with_base (unsigned char encoding, _Unwind_Ptr base,
const unsigned char *p, _Unwind_Ptr *val)
@ -270,6 +273,8 @@ read_encoded_value_with_base (unsigned char encoding, _Unwind_Ptr base,
return p;
}
#pragma GCC diagnostic pop
#ifndef NO_BASE_OF_ENCODED_VALUE
/* Like read_encoded_value_with_base, but get the base from the context