When we set the size and precision of nullptr_t we forgot to set the
alignment, so we end up with unaligned accesses that cause problems on
some targets. The ABI has now been clarified to specify the alignment.
My question is what to do about this for GCC 5.2. This is currently
breaking things on some targets, but it's also a real ABI change. The
effect should be moderated by the fact that nullptr_t has no value, but
if we have a nullptr_t followed by another parameter of a different
type, the location of that parameter could change.
Any thoughts?
commit eba1ee852a6814f0c9dfdc08826c32dfbca3a497
Author: Jason Merrill <ja...@redhat.com>
Date: Fri Jun 19 15:29:33 2015 -0400
PR c++/65945
* decl.c (cxx_init_decl_processing): Set TYPE_ALIGN of nullptr_t.
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 515c2d3..a3fd5b6 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -3995,6 +3995,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
index 0000000..7de365a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/abi/nullptr-align.C
@@ -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 *), "");