aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/init.c
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2016-10-12 14:04:51 -0400
committerJason Merrill <jason@gcc.gnu.org>2016-10-12 14:04:51 -0400
commit2ec69f566076547b618447ba5531260c25abed3e (patch)
treeb0b884a556e7cf9e1c8d1c48712cc88cdddf5671 /gcc/cp/init.c
parentfa8e596366cabd3c91822aee91987879a2eb58fd (diff)
downloadgcc-2ec69f566076547b618447ba5531260c25abed3e.zip
gcc-2ec69f566076547b618447ba5531260c25abed3e.tar.gz
gcc-2ec69f566076547b618447ba5531260c25abed3e.tar.bz2
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
Diffstat (limited to 'gcc/cp/init.c')
-rw-r--r--gcc/cp/init.c41
1 files changed, 26 insertions, 15 deletions
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index b4b5e0a..455995a 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<tree, va_gc> **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<tree, va_gc> **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)