From 2ec69f566076547b618447ba5531260c25abed3e Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Wed, 12 Oct 2016 14:04:51 -0400 Subject: [PATCH] PR c++/77742 - -Waligned-new and placement new. * init.c (build_new_1): Don't -Waligned-new about placement new. (malloc_alignment): New. Consider MALLOC_ABI_ALIGNMENT. * decl.c (cxx_init_decl_processing): New. From-SVN: r241073 --- gcc/cp/ChangeLog | 7 ++++ gcc/cp/cp-tree.h | 1 + gcc/cp/decl.c | 2 +- gcc/cp/init.c | 41 ++++++++++++++--------- gcc/testsuite/g++.dg/cpp1z/aligned-new7.C | 15 +++++++++ 5 files changed, 50 insertions(+), 16 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp1z/aligned-new7.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index ff0435e62ea..b01e196667d 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2016-10-11 Jason Merrill + + PR c++/77742 + * init.c (build_new_1): Don't -Waligned-new about placement new. + (malloc_alignment): New. Consider MALLOC_ABI_ALIGNMENT. + * decl.c (cxx_init_decl_processing): New. + 2016-10-10 Jason Merrill PR c++/77890 diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 8b0442f9ff4..88cae04e69b 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -5953,6 +5953,7 @@ extern tree build_offset_ref (tree, tree, bool, tsubst_flags_t); extern tree throw_bad_array_new_length (void); extern bool type_has_new_extended_alignment (tree); +extern unsigned malloc_alignment (void); extern tree build_new (vec **, tree, tree, vec **, int, tsubst_flags_t); diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 2d11aefbd69..62408931900 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -4082,7 +4082,7 @@ cxx_init_decl_processing (void) if (aligned_new_threshold == -1) aligned_new_threshold = (cxx_dialect >= cxx1z) ? 1 : 0; if (aligned_new_threshold == 1) - aligned_new_threshold = max_align_t_align () / BITS_PER_UNIT; + aligned_new_threshold = malloc_alignment () / BITS_PER_UNIT; { tree newattrs, extvisattr; diff --git a/gcc/cp/init.c b/gcc/cp/init.c index b4b5e0acd45..455995a58d7 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -2589,6 +2589,16 @@ type_has_new_extended_alignment (tree t) && TYPE_ALIGN_UNIT (t) > (unsigned)aligned_new_threshold); } +/* Return the alignment we expect malloc to guarantee. This should just be + MALLOC_ABI_ALIGNMENT, but that macro defaults to only BITS_PER_WORD for some + reason, so don't let the threshold be smaller than max_align_t_align. */ + +unsigned +malloc_alignment () +{ + return MAX (max_align_t_align(), MALLOC_ABI_ALIGNMENT); +} + /* Generate code for a new-expression, including calling the "operator new" function, initializing the object, and, if an exception occurs during construction, cleaning up. The arguments are as for @@ -2974,8 +2984,23 @@ build_new_1 (vec **placement, tree type, tree nelts, gcc_assert (alloc_fn != NULL_TREE); + /* Now, check to see if this function is actually a placement + allocation function. This can happen even when PLACEMENT is NULL + because we might have something like: + + struct S { void* operator new (size_t, int i = 0); }; + + A call to `new S' will get this allocation function, even though + there is no explicit placement argument. If there is more than + one argument, or there are variable arguments, then this is a + placement allocation function. */ + placement_allocation_fn_p + = (type_num_arguments (TREE_TYPE (alloc_fn)) > 1 + || varargs_function_p (alloc_fn)); + if (warn_aligned_new - && TYPE_ALIGN (elt_type) > max_align_t_align () + && !placement_allocation_fn_p + && TYPE_ALIGN (elt_type) > malloc_alignment () && (warn_aligned_new > 1 || CP_DECL_CONTEXT (alloc_fn) == global_namespace) && !aligned_allocation_fn_p (alloc_fn)) @@ -3033,20 +3058,6 @@ build_new_1 (vec **placement, tree type, tree nelts, while (TREE_CODE (alloc_call) == COMPOUND_EXPR) alloc_call = TREE_OPERAND (alloc_call, 1); - /* Now, check to see if this function is actually a placement - allocation function. This can happen even when PLACEMENT is NULL - because we might have something like: - - struct S { void* operator new (size_t, int i = 0); }; - - A call to `new S' will get this allocation function, even though - there is no explicit placement argument. If there is more than - one argument, or there are variable arguments, then this is a - placement allocation function. */ - placement_allocation_fn_p - = (type_num_arguments (TREE_TYPE (alloc_fn)) > 1 - || varargs_function_p (alloc_fn)); - /* Preevaluate the placement args so that we don't reevaluate them for a placement delete. */ if (placement_allocation_fn_p) diff --git a/gcc/testsuite/g++.dg/cpp1z/aligned-new7.C b/gcc/testsuite/g++.dg/cpp1z/aligned-new7.C new file mode 100644 index 00000000000..e12db9b9fad --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1z/aligned-new7.C @@ -0,0 +1,15 @@ +// PR c++/77742 +// { dg-options "-Wall -std=c++1z" } + +#include + +struct X +{ + alignas(2*__STDCPP_DEFAULT_NEW_ALIGNMENT__) int i; +}; + +int main() +{ + alignas(alignof(X)) char buf[sizeof(X)]; + ::new((void*)buf) X{1}; +} -- 2.30.2