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 *), "");

Reply via email to