]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
C/C++: Add -Waddress-of-packed-member
authorH.J. Lu <hongjiu.lu@intel.com>
Thu, 20 Dec 2018 21:41:48 +0000 (21:41 +0000)
committerH.J. Lu <hjl@gcc.gnu.org>
Thu, 20 Dec 2018 21:41:48 +0000 (13:41 -0800)
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

61 files changed:
gcc/ChangeLog
gcc/c-family/ChangeLog
gcc/c-family/c-common.h
gcc/c-family/c-warn.c
gcc/c-family/c.opt
gcc/c/ChangeLog
gcc/c/c-typeck.c
gcc/cp/ChangeLog
gcc/cp/call.c
gcc/cp/typeck.c
gcc/doc/invoke.texi
gcc/testsuite/ChangeLog
gcc/testsuite/c-c++-common/asan/misalign-1.c
gcc/testsuite/c-c++-common/asan/misalign-2.c
gcc/testsuite/c-c++-common/pr51628-1.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/pr51628-10.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/pr51628-11.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/pr51628-12.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/pr51628-13.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/pr51628-14.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/pr51628-15.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/pr51628-16.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/pr51628-2.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/pr51628-26.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/pr51628-27.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/pr51628-28.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/pr51628-29.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/pr51628-3.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/pr51628-30.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/pr51628-31.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/pr51628-32.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/pr51628-4.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/pr51628-5.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/pr51628-6.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/pr51628-7.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/pr51628-8.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/pr51628-9.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/ubsan/align-10.c
gcc/testsuite/c-c++-common/ubsan/align-2.c
gcc/testsuite/c-c++-common/ubsan/align-4.c
gcc/testsuite/c-c++-common/ubsan/align-6.c
gcc/testsuite/c-c++-common/ubsan/align-7.c
gcc/testsuite/c-c++-common/ubsan/align-8.c
gcc/testsuite/g++.dg/ubsan/align-2.C
gcc/testsuite/gcc.dg/pr51628-17.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/pr51628-18.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/pr51628-19.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/pr51628-20.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/pr51628-21.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/pr51628-22.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/pr51628-23.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/pr51628-24.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/pr51628-25.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/avx512bw-vmovdqu16-2.c
gcc/testsuite/gcc.target/i386/avx512f-vmovdqu32-2.c
gcc/testsuite/gcc.target/i386/avx512f-vmovdqu64-2.c
gcc/testsuite/gcc.target/i386/avx512vl-vmovdqu16-2.c
gcc/testsuite/gcc.target/i386/avx512vl-vmovdqu32-2.c
gcc/testsuite/gcc.target/i386/avx512vl-vmovdqu64-2.c
libgcc/ChangeLog
libgcc/unwind-pe.h

index 4be16c15f86185d838fad2cbcd489f8613324fcd..acadee92ef3aee37e1077234b0c8bcf65824ac48 100644 (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
index 8e2527bd0a38da309d10c8cca829a5f49d47a13e..6f08e265803b179eda6a6ab578f5afa6ab18d18e 100644 (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
index 0b9ddf68fe00a36aca93ba17bf28fdb76affadf8..91f5ff4e44544df6dd92478d7077c226d2496e47 100644 (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
index 60132021531ddfa4567eb06b230b4e54ce69f1c8..8f402ee164ed8ea901fae581370060f5d712966d 100644 (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);
+    }
+}
index 07ff1c84f9644ad250f13cb855bfd414cc9ba1b6..22ccf910a8593e87d1853324f51e955333e0b2e9 100644 (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.
index 6e12dda23317582a5fa335b7da356b5353985532..8febd2570dfcf44858e034fa70cde0ff34324431 100644 (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
index 1ae5ede81e603f61c0fbf0fad6893df1a0f0cbc4..2fe3f64f455a9029a87b40429d7031d9bf24234e 100644 (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)
index 7680b549c27f2083fcd1b5a9e25e8fdd37d31bc6..f6e07a3afdba03c455a20e6edcc8f9681038fe42 100644 (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
index e2f8fe1063075d2911d6fe393d96a21c6d7bcf5c..cd220d70df5909cc788e5165219e08c762c0b4d6 100644 (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;
 }
 
index ef317f5cc7dce71bf1a70cd80cfceccd303575a8..d5d1115fd239dfada00a80d97efd98fe8647dabb 100644 (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);
 }
index ac2ee59d92c3d5bd0e9deb854ba9fcb3dcee4ec9..14365fba501e29042a15202ba6c28c61ce2ffa6b 100644 (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
index 33a4776b9212c078fef4d49a0997f7a824afb5eb..8a32fa8998f539ecaf3ddff8647968f6f1ca581c 100644 (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
index 5cd605ac045407cdaf69814aa04c78ff7158a91d..ebeb03067063f65f58be2b49c3985a1e649a1972 100644 (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" } */
 
index a6ed49bac0537b6a10004582dd5fe7f3f0a42cd0..b27e22d35a821cf03785cbfba1a0a858794871f7 100644 (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" } */
 
diff --git a/gcc/testsuite/c-c++-common/pr51628-1.c b/gcc/testsuite/c-c++-common/pr51628-1.c
new file mode 100644 (file)
index 0000000..5324f9c
--- /dev/null
@@ -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;
+}
diff --git a/gcc/testsuite/c-c++-common/pr51628-10.c b/gcc/testsuite/c-c++-common/pr51628-10.c
new file mode 100644 (file)
index 0000000..085fe16
--- /dev/null
@@ -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;
+}
diff --git a/gcc/testsuite/c-c++-common/pr51628-11.c b/gcc/testsuite/c-c++-common/pr51628-11.c
new file mode 100644 (file)
index 0000000..7661232
--- /dev/null
@@ -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);
diff --git a/gcc/testsuite/c-c++-common/pr51628-12.c b/gcc/testsuite/c-c++-common/pr51628-12.c
new file mode 100644 (file)
index 0000000..bc221fa
--- /dev/null
@@ -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 } */
diff --git a/gcc/testsuite/c-c++-common/pr51628-13.c b/gcc/testsuite/c-c++-common/pr51628-13.c
new file mode 100644 (file)
index 0000000..0edd5e7
--- /dev/null
@@ -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 } */
diff --git a/gcc/testsuite/c-c++-common/pr51628-14.c b/gcc/testsuite/c-c++-common/pr51628-14.c
new file mode 100644 (file)
index 0000000..f50378b
--- /dev/null
@@ -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; }
diff --git a/gcc/testsuite/c-c++-common/pr51628-15.c b/gcc/testsuite/c-c++-common/pr51628-15.c
new file mode 100644 (file)
index 0000000..bcac6d7
--- /dev/null
@@ -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 } */
+}
diff --git a/gcc/testsuite/c-c++-common/pr51628-16.c b/gcc/testsuite/c-c++-common/pr51628-16.c
new file mode 100644 (file)
index 0000000..cd502fe
--- /dev/null
@@ -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 } */
diff --git a/gcc/testsuite/c-c++-common/pr51628-2.c b/gcc/testsuite/c-c++-common/pr51628-2.c
new file mode 100644 (file)
index 0000000..abfb84d
--- /dev/null
@@ -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;
+}
diff --git a/gcc/testsuite/c-c++-common/pr51628-26.c b/gcc/testsuite/c-c++-common/pr51628-26.c
new file mode 100644 (file)
index 0000000..2042379
--- /dev/null
@@ -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 } */
+}
diff --git a/gcc/testsuite/c-c++-common/pr51628-27.c b/gcc/testsuite/c-c++-common/pr51628-27.c
new file mode 100644 (file)
index 0000000..9ae1efd
--- /dev/null
@@ -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 } */
diff --git a/gcc/testsuite/c-c++-common/pr51628-28.c b/gcc/testsuite/c-c++-common/pr51628-28.c
new file mode 100644 (file)
index 0000000..3cc1fec
--- /dev/null
@@ -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));
+}
diff --git a/gcc/testsuite/c-c++-common/pr51628-29.c b/gcc/testsuite/c-c++-common/pr51628-29.c
new file mode 100644 (file)
index 0000000..94b3722
--- /dev/null
@@ -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 } */
+}
diff --git a/gcc/testsuite/c-c++-common/pr51628-3.c b/gcc/testsuite/c-c++-common/pr51628-3.c
new file mode 100644 (file)
index 0000000..0ea94c8
--- /dev/null
@@ -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 } */
+}
diff --git a/gcc/testsuite/c-c++-common/pr51628-30.c b/gcc/testsuite/c-c++-common/pr51628-30.c
new file mode 100644 (file)
index 0000000..578edf4
--- /dev/null
@@ -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 } */
+}
diff --git a/gcc/testsuite/c-c++-common/pr51628-31.c b/gcc/testsuite/c-c++-common/pr51628-31.c
new file mode 100644 (file)
index 0000000..9730f53
--- /dev/null
@@ -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 } */
+}
diff --git a/gcc/testsuite/c-c++-common/pr51628-32.c b/gcc/testsuite/c-c++-common/pr51628-32.c
new file mode 100644 (file)
index 0000000..a62e57d
--- /dev/null
@@ -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 } */
diff --git a/gcc/testsuite/c-c++-common/pr51628-4.c b/gcc/testsuite/c-c++-common/pr51628-4.c
new file mode 100644 (file)
index 0000000..c4c1fb7
--- /dev/null
@@ -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 } */
+}
diff --git a/gcc/testsuite/c-c++-common/pr51628-5.c b/gcc/testsuite/c-c++-common/pr51628-5.c
new file mode 100644 (file)
index 0000000..9d7c309
--- /dev/null
@@ -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 } */
+}
diff --git a/gcc/testsuite/c-c++-common/pr51628-6.c b/gcc/testsuite/c-c++-common/pr51628-6.c
new file mode 100644 (file)
index 0000000..52aa07a
--- /dev/null
@@ -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 } */
+}
diff --git a/gcc/testsuite/c-c++-common/pr51628-7.c b/gcc/testsuite/c-c++-common/pr51628-7.c
new file mode 100644 (file)
index 0000000..ae4a681
--- /dev/null
@@ -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];
+}
diff --git a/gcc/testsuite/c-c++-common/pr51628-8.c b/gcc/testsuite/c-c++-common/pr51628-8.c
new file mode 100644 (file)
index 0000000..cc2dae0
--- /dev/null
@@ -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 } */
+}
diff --git a/gcc/testsuite/c-c++-common/pr51628-9.c b/gcc/testsuite/c-c++-common/pr51628-9.c
new file mode 100644 (file)
index 0000000..0470aa3
--- /dev/null
@@ -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 } */
+}
index 56ae9ebfe306f4347708db2e719cc053ba437a11..6210533173c644076ec7417a7c851551e3e3095b 100644 (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]; };
index 071de8c202a782b7bf363edd196b9ce15ce3f9f3..336b1c3c90775723a953f3df6fb9e12769287824 100644 (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; };
index 3252595d33014311345cd66362897bd584425d7f..d5feeee29c6641de55460430051f4846c6b1ef72 100644 (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"
 
index 3364746fb277d46033d1c5829e48960770fb87e3..0302b7b889468ba42fa6c2cd5f8bd848d399e555 100644 (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; };
index ec4e87f56d518de370d74f7bea424c09e92ffad6..dd1e8c91cefd88c55aeb34a56592336b47a7e2ad 100644 (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" } */
 
index 61c1ceb6682f260f24d74b0d22cb2334c98fcb81..5fe0e0fe9312b72c4af8c1d97126873e35a9c6d0 100644 (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" } */
 
index 3e4f5485d02b2944408acfafcf57eda4823ff2d2..c97ede88392a3a0fc2b437a122f7390f670f1a7c 100644 (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;
diff --git a/gcc/testsuite/gcc.dg/pr51628-17.c b/gcc/testsuite/gcc.dg/pr51628-17.c
new file mode 100644 (file)
index 0000000..0be95b2
--- /dev/null
@@ -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 } */
diff --git a/gcc/testsuite/gcc.dg/pr51628-18.c b/gcc/testsuite/gcc.dg/pr51628-18.c
new file mode 100644 (file)
index 0000000..03a04ef
--- /dev/null
@@ -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];
+}
diff --git a/gcc/testsuite/gcc.dg/pr51628-19.c b/gcc/testsuite/gcc.dg/pr51628-19.c
new file mode 100644 (file)
index 0000000..7ff03e8
--- /dev/null
@@ -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 } */
+}
diff --git a/gcc/testsuite/gcc.dg/pr51628-20.c b/gcc/testsuite/gcc.dg/pr51628-20.c
new file mode 100644 (file)
index 0000000..8088828
--- /dev/null
@@ -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 } */
diff --git a/gcc/testsuite/gcc.dg/pr51628-21.c b/gcc/testsuite/gcc.dg/pr51628-21.c
new file mode 100644 (file)
index 0000000..3077e72
--- /dev/null
@@ -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 } */
diff --git a/gcc/testsuite/gcc.dg/pr51628-22.c b/gcc/testsuite/gcc.dg/pr51628-22.c
new file mode 100644 (file)
index 0000000..1bd5d79
--- /dev/null
@@ -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 } */
diff --git a/gcc/testsuite/gcc.dg/pr51628-23.c b/gcc/testsuite/gcc.dg/pr51628-23.c
new file mode 100644 (file)
index 0000000..5709be6
--- /dev/null
@@ -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; }
diff --git a/gcc/testsuite/gcc.dg/pr51628-24.c b/gcc/testsuite/gcc.dg/pr51628-24.c
new file mode 100644 (file)
index 0000000..3ad99cd
--- /dev/null
@@ -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 } */
diff --git a/gcc/testsuite/gcc.dg/pr51628-25.c b/gcc/testsuite/gcc.dg/pr51628-25.c
new file mode 100644 (file)
index 0000000..2fc5c02
--- /dev/null
@@ -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 } */
index a61609c40d21d0ffdbeb7010c5bab4c3b638773f..c6e3ebdc507894dd0c63c77d715a48cf2c50cf90 100644 (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
index f2edc3dff7b5d6296e6ff08c848ce6c0bbfffc6d..95a657fc5ff2b066bc219a2ffd75eb925dced6e1 100644 (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
index 14176965ace37dbe059c1232f234c944ef8c1f06..954b091d9760f6febc719d8e863166286ebd1164 100644 (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
index 45ae83d4552e22d19127b50da9f7dc9807b14dc8..81465f8d9a0192d5fe7b18739aee1d3380343f30 100644 (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 } */
 
index 4b928d0cd42287acd6b4a9eae46c915506982678..19390664bd090174208d446559517b0a50fa7d07 100644 (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
index 1863ed3616fa54f65ae43545d4291046fc68c96e..aea0c12a5ff2afd848d9dda0883966750f800972 100644 (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
index 1879424524d5f1cb8256b82aaf6e7904ffecafac..1d2dc17a1a6a06a5f45b52060841aa51c91ad494 100644 (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
index dd5ae95fc2c4a5e6b2b4d2358a28300176084a76..05c2fb4dd5076587ed23dbe1aab90531c1e16e78 100644 (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