diff options
author | Jason Merrill <jason@redhat.com> | 2015-07-01 13:59:19 -0400 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2015-07-01 13:59:19 -0400 |
commit | d68f848b12654cb359951eb24608d9e1b5f05e64 (patch) | |
tree | 02021abfb17f1a5128da0a9911f59033583619eb | |
parent | f9a12f7b8fd56359f1eee124309fc783f83466b5 (diff) | |
download | gcc-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/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/cp/class.c | 19 | ||||
-rw-r--r-- | gcc/cp/decl.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/abi/nullptr-align.C | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/abi/nullptr-align2.C | 20 |
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" } +}; |