From d68f848b12654cb359951eb24608d9e1b5f05e64 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Wed, 1 Jul 2015 13:59:19 -0400 Subject: [PATCH] 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 --- gcc/cp/ChangeLog | 7 +++++++ gcc/cp/class.c | 19 +++++++++++++++++++ gcc/cp/decl.c | 2 ++ gcc/testsuite/g++.dg/abi/nullptr-align.C | 5 +++++ gcc/testsuite/g++.dg/abi/nullptr-align2.C | 20 ++++++++++++++++++++ 5 files changed, 53 insertions(+) create mode 100644 gcc/testsuite/g++.dg/abi/nullptr-align.C create mode 100644 gcc/testsuite/g++.dg/abi/nullptr-align2.C 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 + + 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 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" } +}; -- 2.7.4