aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2015-07-01 13:59:19 -0400
committerJason Merrill <jason@gcc.gnu.org>2015-07-01 13:59:19 -0400
commitd68f848b12654cb359951eb24608d9e1b5f05e64 (patch)
tree02021abfb17f1a5128da0a9911f59033583619eb
parentf9a12f7b8fd56359f1eee124309fc783f83466b5 (diff)
downloadgcc-d68f848b12654cb359951eb24608d9e1b5f05e64.zip
gcc-d68f848b12654cb359951eb24608d9e1b5f05e64.tar.gz
gcc-d68f848b12654cb359951eb24608d9e1b5f05e64.tar.bz2
re PR c++/65945 (C++ alignment of nullptr_t is 1 and might cause unaligned stores to the frame)
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
-rw-r--r--gcc/cp/ChangeLog7
-rw-r--r--gcc/cp/class.c19
-rw-r--r--gcc/cp/decl.c2
-rw-r--r--gcc/testsuite/g++.dg/abi/nullptr-align.C5
-rw-r--r--gcc/testsuite/g++.dg/abi/nullptr-align2.C20
5 files changed, 53 insertions, 0 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 33fe38e..2ade465 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 2547b91..b5f2c34 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -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;
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 9fabde7..8bea2e3 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -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
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" }
+};