@@ -1270,6 +1270,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_of_packed_member (tree, tree);
/* Places where an lvalue, or modifiable lvalue, may be required.
Used to select diagnostic messages in lvalue_error and
@@ -2587,3 +2587,120 @@ 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 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)
+{
+ tree base;
+ tree object;
+ tree field;
+
+ if (INDIRECT_REF_P (rhs))
+ rhs = TREE_OPERAND (rhs, 0);
+
+ switch (TREE_CODE (rhs))
+ {
+ case ADDR_EXPR:
+ base = TREE_OPERAND (rhs, 0);
+ while (TREE_CODE (base) == ARRAY_REF)
+ base = TREE_OPERAND (base, 0);
+ if (TREE_CODE (base) != COMPONENT_REF)
+ return NULL_TREE;
+ object = TREE_OPERAND (base, 0);
+ field = TREE_OPERAND (base, 1);
+ break;
+ case COMPONENT_REF:
+ object = TREE_OPERAND (rhs, 0);
+ field = TREE_OPERAND (rhs, 1);
+ break;
+ default:
+ return NULL_TREE;
+ }
+
+ tree context;
+ unsigned int type_align, record_align;
+
+ /* Check alignment of the data member. */
+ if (TREE_CODE (field) == FIELD_DECL && DECL_PACKED (field))
+ {
+ /* Check the expected alignment against the field alignment. */
+ type_align = TYPE_ALIGN (type);
+ context = DECL_CONTEXT (field);
+ 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;
+ }
+
+ /* Check alignment of the object. */
+ if (TREE_CODE (object) == COMPONENT_REF)
+ {
+ field = TREE_OPERAND (object, 1);
+ if (TREE_CODE (field) == FIELD_DECL && DECL_PACKED (field))
+ {
+ type_align = TYPE_ALIGN (type);
+ context = DECL_CONTEXT (field);
+ record_align = TYPE_ALIGN (context);
+ if ((record_align % type_align) != 0)
+ return context;
+ }
+ }
+
+ return NULL_TREE;
+}
+
+/* Warn 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. */
+
+void
+warn_for_address_of_packed_member (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;
+
+ /* Get the type of the pointer pointing to. */
+ type = TREE_TYPE (type);
+
+ if (TREE_CODE (rhs) == NOP_EXPR)
+ rhs = TREE_OPERAND (rhs, 0);
+
+ tree context;
+
+ if (TREE_CODE (rhs) == COND_EXPR)
+ {
+ /* Check the THEN path first. */
+ tree op1 = TREE_OPERAND (rhs, 1);
+ context = check_address_of_packed_member (type, op1);
+ if (context)
+ rhs = op1;
+ else
+ {
+ /* Check the ELSE path. */
+ rhs = TREE_OPERAND (rhs, 2);
+ context = check_address_of_packed_member (type, rhs);
+ }
+ }
+ else
+ 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);
+ }
+}
@@ -599,6 +599,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.
@@ -6289,6 +6289,54 @@ inform_for_arg (tree fundecl, location_t ploc, int parmnum,
expected_type, actual_type);
}
+/* Warn if the right hand poiner value RHS isn't aligned to a
+ pointer type TYPE. ERRTYPE says whether it is argument passing,
+ assignment, initialization or return. PARMNUM is the number of
+ the argument, for printing in error messages. NAME is the name
+ of the function. */
+
+static void
+warn_for_pointer_of_packed_member (location_t location, tree type,
+ tree rhs)
+{
+ if (!warn_address_of_packed_member || !POINTER_TYPE_P (type))
+ return;
+
+ bool pointer_p;
+ tree rhstype;
+
+ /* Check the original type of LHS. */
+ switch (TREE_CODE (rhs))
+ {
+ case PARM_DECL:
+ case VAR_DECL:
+ rhstype = TREE_TYPE (rhs);
+ pointer_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);
+ pointer_p = TREE_CODE (rhstype) == ARRAY_TYPE;
+ break;
+ default:
+ return;
+ }
+
+ if (pointer_p
+ && TYPE_PACKED (TREE_TYPE (rhstype)))
+ {
+ unsigned int type_align = TYPE_ALIGN (TREE_TYPE (type));
+ unsigned int rhs_align = TYPE_ALIGN (TREE_TYPE (rhstype));
+ if ((rhs_align % type_align) != 0)
+ warning_at (location, OPT_Waddress_of_packed_member,
+ "taking value of packed %qT may result in an "
+ "unaligned pointer value",
+ rhstype);
+ }
+}
+
/* Convert value RHS to type TYPE as preparation for an assignment to
an lvalue of type TYPE. If ORIGTYPE is not NULL_TREE, it is the
original type of RHS; this differs from TREE_TYPE (RHS) for enum
@@ -6499,7 +6547,10 @@ 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_of_packed_member (type, orig_rhs);
+ return rhs;
+ }
if (coder == VOID_TYPE)
{
@@ -6986,6 +7037,13 @@ convert_for_assignment (location_t location, location_t expr_loc, tree type,
}
}
+ /* If LHS is't an address, check pointer or array of packed
+ struct or union. */
+ if (TREE_CODE (orig_rhs) != ADDR_EXPR)
+ warn_for_pointer_of_packed_member (location, type, orig_rhs);
+ else
+ warn_for_address_of_packed_member (type, orig_rhs);
+
return convert (type, rhs);
}
else if (codel == POINTER_TYPE && coder == ARRAY_TYPE)
@@ -7446,6 +7446,9 @@ convert_for_arg_passing (tree type, tree val, tsubst_flags_t complain)
}
maybe_warn_parm_abi (type, EXPR_LOC_OR_LOC (val, input_location));
}
+
+ warn_for_address_of_packed_member (type, val);
+
return val;
}
@@ -8903,6 +8903,8 @@ convert_for_assignment (tree type, tree rhs,
TREE_NO_WARNING (rhs) = 1;
}
+ warn_for_address_of_packed_member (type, rhs);
+
return perform_implicit_conversion_flags (strip_top_quals (type), rhs,
complain, flags);
}
@@ -260,8 +260,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 @gol
--Walloc-zero -Walloc-size-larger-than=@var{n}
+-w -Wextra -Wall -Waddress -Waddress-of-packed-member @gol
+-Waggregate-return -Walloc-zero -Walloc-size-larger-than=@var{n} @gol
-Walloca -Walloca-larger-than=@var{n} @gol
-Wno-aggressive-loop-optimizations -Warray-bounds -Warray-bounds=@var{n} @gol
-Wno-attributes -Wbool-compare -Wbool-operation @gol
@@ -6469,6 +6469,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
@@ -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" } */
@@ -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" } */
new file mode 100644
@@ -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;
+}
new file mode 100644
@@ -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;
+}
new file mode 100644
@@ -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);
new file mode 100644
@@ -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 } */
new file mode 100644
@@ -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 } */
new file mode 100644
@@ -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; }
new file mode 100644
@@ -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 } */
+}
new file mode 100644
@@ -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;
+}
new file mode 100644
@@ -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 } */
+}
new file mode 100644
@@ -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 } */
+}
new file mode 100644
@@ -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 } */
+}
new file mode 100644
@@ -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 } */
+}
new file mode 100644
@@ -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];
+}
new file mode 100644
@@ -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 } */
+}
new file mode 100644
@@ -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 } */
+}
@@ -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]; };
@@ -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; };
@@ -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"
@@ -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; };
@@ -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" } */
@@ -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" } */
@@ -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;
new file mode 100644
@@ -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 result in an unaligned pointer value" "" { target *-*-* } .-1 } */
new file mode 100644
@@ -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 } */
new file mode 100644
@@ -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];
+}
new file mode 100644
@@ -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 } */
+}
new file mode 100644
@@ -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 result in an unaligned pointer value" "" { target *-*-* } .-1 } */
new file mode 100644
@@ -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 result in an unaligned pointer value" "" { target *-*-* } .-1 } */
new file mode 100644
@@ -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 } */
new file mode 100644
@@ -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; }
new file mode 100644
@@ -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 } */
@@ -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
@@ -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
@@ -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
@@ -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 } */
@@ -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
@@ -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
@@ -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