re PR c++/65945 (C++ alignment of nullptr_t is 1 and might cause unaligned stores...
authorJason Merrill <jason@redhat.com>
Wed, 1 Jul 2015 17:59:19 +0000 (13:59 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Wed, 1 Jul 2015 17:59:19 +0000 (13:59 -0400)
PR c++/65945
* decl.c (cxx_init_decl_processing): Set TYPE_ALIGN of nullptr_t.
* class.c (layout_nonempty_base_or_field): Warn if that affects
the offset of a field.

From-SVN: r225270

gcc/cp/ChangeLog
gcc/cp/class.c
gcc/cp/decl.c
gcc/testsuite/g++.dg/abi/nullptr-align.C [new file with mode: 0644]
gcc/testsuite/g++.dg/abi/nullptr-align2.C [new file with mode: 0644]

index 33fe38e..2ade465 100644 (file)
@@ -1,3 +1,10 @@
+2015-07-01  Jason Merrill  <jason@redhat.com>
+
+       PR c++/65945
+       * decl.c (cxx_init_decl_processing): Set TYPE_ALIGN of nullptr_t.
+       * class.c (layout_nonempty_base_or_field): Warn if that affects
+       the offset of a field.
+
 2015-07-01  Paolo Carlini  <paolo.carlini@oracle.com>
 
        PR c++/60365
index 2547b91..b5f2c34 100644 (file)
@@ -4281,6 +4281,25 @@ layout_nonempty_base_or_field (record_layout_info rli,
                                       : TYPE_ALIGN (type)));
          normalize_rli (rli);
        }
+      else if (TREE_CODE (type) == NULLPTR_TYPE
+              && warn_abi && abi_version_crosses (9))
+       {
+         /* Before ABI v9, we were giving nullptr_t alignment of 1; if
+            the offset wasn't aligned like a pointer when we started to
+            layout this field, that affects its position.  */
+         tree pos = rli_size_unit_so_far (&old_rli);
+         if (int_cst_value (pos) % TYPE_ALIGN_UNIT (ptr_type_node) != 0)
+           {
+             if (abi_version_at_least (9))
+               warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wabi,
+                           "alignment of %qD increased in -fabi-version=9 "
+                           "(GCC 5.2)", decl);
+             else
+               warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wabi, "alignment "
+                           "of %qD will increase in -fabi-version=9", decl);
+           }
+         break;
+       }
       else
        /* There was no conflict.  We're done laying out this field.  */
        break;
index 9fabde7..8bea2e3 100644 (file)
@@ -4007,6 +4007,8 @@ cxx_init_decl_processing (void)
     TYPE_SIZE_UNIT (nullptr_type_node) = size_int (GET_MODE_SIZE (ptr_mode));
     TYPE_UNSIGNED (nullptr_type_node) = 1;
     TYPE_PRECISION (nullptr_type_node) = GET_MODE_BITSIZE (ptr_mode);
+    if (abi_version_at_least (9))
+      TYPE_ALIGN (nullptr_type_node) = GET_MODE_ALIGNMENT (ptr_mode);
     SET_TYPE_MODE (nullptr_type_node, ptr_mode);
     record_builtin_type (RID_MAX, "decltype(nullptr)", nullptr_type_node);
     nullptr_node = build_int_cst (nullptr_type_node, 0);
diff --git a/gcc/testsuite/g++.dg/abi/nullptr-align.C b/gcc/testsuite/g++.dg/abi/nullptr-align.C
new file mode 100644 (file)
index 0000000..7de365a
--- /dev/null
@@ -0,0 +1,5 @@
+// PR c++/65945
+// { dg-do compile { target c++11 } }
+// { dg-options "-fabi-version=9" }
+
+static_assert(alignof (decltype (nullptr)) == alignof (void *), "");
diff --git a/gcc/testsuite/g++.dg/abi/nullptr-align2.C b/gcc/testsuite/g++.dg/abi/nullptr-align2.C
new file mode 100644 (file)
index 0000000..66a9011
--- /dev/null
@@ -0,0 +1,20 @@
+// { dg-do compile { target c++11 } }
+// { dg-options "-fabi-version=0 -Wabi=8" }
+
+struct A
+{
+  decltype(nullptr) n;
+  decltype(nullptr) n2;
+};
+
+struct B
+{
+  void *p;
+  decltype(nullptr) n;
+};
+
+struct C
+{
+  char c;
+  decltype(nullptr) n;         // { dg-warning "alignment" }
+};