This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
C++ PATCH for c++/65945 (nullptr_t alignment)
- From: Jason Merrill <jason at redhat dot com>
- To: gcc-patches List <gcc-patches at gcc dot gnu dot org>
- Date: Wed, 01 Jul 2015 13:09:09 -0400
- Subject: C++ PATCH for c++/65945 (nullptr_t alignment)
- Authentication-results: sourceware.org; auth=none
It's trivial to fix the alignment of nullptr_t, but I was concerned
about ABI impact. On further research it seems that it won't cause any
trouble with argument alignment, since that doesn't seem to rely on
TYPE_ALIGN at all; I think the only ABI breakage would come from
unaligned nullptr_t fields in classes, which I expect to be very rare.
The testcases that were breaking on SPARC and ARM without this fix have
to do with local stack slots, which are not part of an interface.
Activating the warning requires passing an explicit version number to
-Wabi, e.g. -Wabi=8.
Tested x86_64-pc-linux-gnu, applying to trunk and 5.
commit 6ec8347672eec505f13f03f3612a847327a96815
Author: Jason Merrill <jason@redhat.com>
Date: Fri Jun 19 15:29:33 2015 -0400
PR c++/65945
gcc/c-family/
* c-opts.c (c_common_post_options): Highest ABI version is 9.
gcc/cp/
* 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.
diff --git a/gcc/c-family/c-opts.c b/gcc/c-family/c-opts.c
index 1a67b5a..718a052 100644
--- a/gcc/c-family/c-opts.c
+++ b/gcc/c-family/c-opts.c
@@ -889,7 +889,7 @@ c_common_post_options (const char **pfilename)
/* Change flag_abi_version to be the actual current ABI level for the
benefit of c_cpp_builtins. */
if (flag_abi_version == 0)
- flag_abi_version = 8;
+ flag_abi_version = 9;
if (cxx_dialect >= cxx11)
{
diff --git a/gcc/common.opt b/gcc/common.opt
index e5553cd..1218a71 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -833,6 +833,9 @@ Driver Undocumented
; 8: The version of the ABI that corrects the substitution behavior of
; function types with function-cv-qualifiers.
; First selectable in G++ 4.9 and default in G++ 5
+;
+; 9: The version of the ABI that corrects the alignment of nullptr_t.
+; First selectable and default in G++ 5.2.
; (set in c_common_post_options).
;
; Additional positive integers will be assigned as new versions of
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 12e62df..d59d351 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -4286,6 +4286,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;
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 0adb3ce..d24b02a 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -4013,6 +4013,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/macro0.C b/gcc/testsuite/g++.dg/abi/macro0.C
index fbcbb2c..35b8769 100644
--- a/gcc/testsuite/g++.dg/abi/macro0.C
+++ b/gcc/testsuite/g++.dg/abi/macro0.C
@@ -1,6 +1,6 @@
// This testcase will need to be kept in sync with c_common_post_options.
// { dg-options "-fabi-version=0" }
-#if __GXX_ABI_VERSION != 1008
+#if __GXX_ABI_VERSION != 1009
#error "Incorrect value of __GXX_ABI_VERSION"
#endif
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 *), "");
diff --git a/gcc/testsuite/g++.dg/abi/nullptr-align2.C b/gcc/testsuite/g++.dg/abi/nullptr-align2.C
new file mode 100644
index 0000000..66a9011
--- /dev/null
+++ b/gcc/testsuite/g++.dg/abi/nullptr-align2.C
@@ -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" }
+};