Commit 2ec69f56 by Jason Merrill Committed by Jason Merrill

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
parent fa8e5963
2016-10-11 Jason Merrill <jason@redhat.com>
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 <jason@redhat.com> 2016-10-10 Jason Merrill <jason@redhat.com>
PR c++/77890 PR c++/77890
......
...@@ -5953,6 +5953,7 @@ extern tree build_offset_ref (tree, tree, bool, ...@@ -5953,6 +5953,7 @@ extern tree build_offset_ref (tree, tree, bool,
tsubst_flags_t); tsubst_flags_t);
extern tree throw_bad_array_new_length (void); extern tree throw_bad_array_new_length (void);
extern bool type_has_new_extended_alignment (tree); extern bool type_has_new_extended_alignment (tree);
extern unsigned malloc_alignment (void);
extern tree build_new (vec<tree, va_gc> **, tree, tree, extern tree build_new (vec<tree, va_gc> **, tree, tree,
vec<tree, va_gc> **, int, vec<tree, va_gc> **, int,
tsubst_flags_t); tsubst_flags_t);
......
...@@ -4082,7 +4082,7 @@ cxx_init_decl_processing (void) ...@@ -4082,7 +4082,7 @@ cxx_init_decl_processing (void)
if (aligned_new_threshold == -1) if (aligned_new_threshold == -1)
aligned_new_threshold = (cxx_dialect >= cxx1z) ? 1 : 0; aligned_new_threshold = (cxx_dialect >= cxx1z) ? 1 : 0;
if (aligned_new_threshold == 1) 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; tree newattrs, extvisattr;
......
...@@ -2589,6 +2589,16 @@ type_has_new_extended_alignment (tree t) ...@@ -2589,6 +2589,16 @@ type_has_new_extended_alignment (tree t)
&& TYPE_ALIGN_UNIT (t) > (unsigned)aligned_new_threshold); && 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 /* Generate code for a new-expression, including calling the "operator
new" function, initializing the object, and, if an exception occurs new" function, initializing the object, and, if an exception occurs
during construction, cleaning up. The arguments are as for 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, ...@@ -2974,8 +2984,23 @@ build_new_1 (vec<tree, va_gc> **placement, tree type, tree nelts,
gcc_assert (alloc_fn != NULL_TREE); 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 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 && (warn_aligned_new > 1
|| CP_DECL_CONTEXT (alloc_fn) == global_namespace) || CP_DECL_CONTEXT (alloc_fn) == global_namespace)
&& !aligned_allocation_fn_p (alloc_fn)) && !aligned_allocation_fn_p (alloc_fn))
...@@ -3033,20 +3058,6 @@ build_new_1 (vec<tree, va_gc> **placement, tree type, tree nelts, ...@@ -3033,20 +3058,6 @@ build_new_1 (vec<tree, va_gc> **placement, tree type, tree nelts,
while (TREE_CODE (alloc_call) == COMPOUND_EXPR) while (TREE_CODE (alloc_call) == COMPOUND_EXPR)
alloc_call = TREE_OPERAND (alloc_call, 1); 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 /* Preevaluate the placement args so that we don't reevaluate them for a
placement delete. */ placement delete. */
if (placement_allocation_fn_p) if (placement_allocation_fn_p)
......
// PR c++/77742
// { dg-options "-Wall -std=c++1z" }
#include <new>
struct X
{
alignas(2*__STDCPP_DEFAULT_NEW_ALIGNMENT__) int i;
};
int main()
{
alignas(alignof(X)) char buf[sizeof(X)];
::new((void*)buf) X{1};
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment