summaryrefslogtreecommitdiff
path: root/gcc/cp/init.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cp/init.c')
-rw-r--r--gcc/cp/init.c67
1 files changed, 56 insertions, 11 deletions
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index 1a5766a42b7..e869542e757 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -2569,6 +2569,15 @@ warn_placement_new_too_small (tree type, tree nelts, tree size, tree oper)
}
}
+/* True if alignof(T) > __STDCPP_DEFAULT_NEW_ALIGNMENT__. */
+
+bool
+type_has_new_extended_alignment (tree t)
+{
+ return (aligned_new_threshhold
+ && TYPE_ALIGN_UNIT (t) > (unsigned)aligned_new_threshhold);
+}
+
/* 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
@@ -2840,6 +2849,10 @@ build_new_1 (vec<tree, va_gc> **placement, tree type, tree nelts,
}
}
+ tree align_arg = NULL_TREE;
+ if (type_has_new_extended_alignment (elt_type))
+ align_arg = build_int_cst (align_type_node, TYPE_ALIGN_UNIT (elt_type));
+
alloc_fn = NULL_TREE;
/* If PLACEMENT is a single simple pointer type not passed by
@@ -2954,12 +2967,28 @@ build_new_1 (vec<tree, va_gc> **placement, tree type, tree nelts,
}
return error_mark_node;
}
- alloc_call = build_new_method_call (build_dummy_object (elt_type),
- fns, placement,
- /*conversion_path=*/NULL_TREE,
- LOOKUP_NORMAL,
- &alloc_fn,
- complain);
+ tree dummy = build_dummy_object (elt_type);
+ alloc_call = NULL_TREE;
+ if (align_arg)
+ {
+ vec<tree, va_gc> *align_args
+ = vec_copy_and_insert (*placement, align_arg, 1);
+ alloc_call
+ = build_new_method_call (dummy, fns, &align_args,
+ /*conversion_path=*/NULL_TREE,
+ LOOKUP_NORMAL, &alloc_fn, tf_none);
+ /* If no matching function is found and the allocated object type
+ has new-extended alignment, the alignment argument is removed
+ from the argument list, and overload resolution is performed
+ again. */
+ if (alloc_call == error_mark_node)
+ alloc_call = NULL_TREE;
+ }
+ if (!alloc_call)
+ alloc_call = build_new_method_call (dummy, fns, placement,
+ /*conversion_path=*/NULL_TREE,
+ LOOKUP_NORMAL,
+ &alloc_fn, complain);
}
else
{
@@ -2976,6 +3005,7 @@ build_new_1 (vec<tree, va_gc> **placement, tree type, tree nelts,
alloc_call = build_operator_new_call (fnname, placement,
&size, &cookie_size,
+ align_arg,
outer_nelts_check,
&alloc_fn, complain);
}
@@ -2986,6 +3016,20 @@ build_new_1 (vec<tree, va_gc> **placement, tree type, tree nelts,
gcc_assert (alloc_fn != NULL_TREE);
+ if (warn_aligned_new
+ && TYPE_ALIGN (elt_type) > max_align_t_align ()
+ && (warn_aligned_new > 1
+ || CP_DECL_CONTEXT (alloc_fn) == global_namespace)
+ && !aligned_allocation_fn_p (alloc_fn))
+ {
+ warning (OPT_Waligned_new_, "%<new%> of type %qT with extended "
+ "alignment %d", elt_type, TYPE_ALIGN_UNIT (elt_type));
+ inform (input_location, "uses %qD, which does not have an alignment "
+ "parameter", alloc_fn);
+ inform (input_location, "use %<-faligned-new%> to enable C++17 "
+ "over-aligned new support");
+ }
+
/* If we found a simple case of PLACEMENT_EXPR above, then copy it
into a temporary variable. */
if (!processing_template_decl
@@ -4052,13 +4096,14 @@ build_vec_init (tree base, tree maxindex, tree init,
finish_expr_stmt (one_init);
current_stmt_tree ()->stmts_are_full_exprs_p = 0;
- one_init = cp_build_unary_op (PREINCREMENT_EXPR, base, 0, complain);
+ one_init = cp_build_unary_op (PREINCREMENT_EXPR, base, false,
+ complain);
if (one_init == error_mark_node)
errors = true;
else
finish_expr_stmt (one_init);
- one_init = cp_build_unary_op (PREDECREMENT_EXPR, iterator, 0,
+ one_init = cp_build_unary_op (PREDECREMENT_EXPR, iterator, false,
complain);
if (one_init == error_mark_node)
errors = true;
@@ -4111,7 +4156,7 @@ build_vec_init (tree base, tree maxindex, tree init,
finish_for_cond (build2 (GT_EXPR, boolean_type_node, iterator,
build_int_cst (TREE_TYPE (iterator), -1)),
for_stmt, false);
- elt_init = cp_build_unary_op (PREDECREMENT_EXPR, iterator, 0,
+ elt_init = cp_build_unary_op (PREDECREMENT_EXPR, iterator, false,
complain);
if (elt_init == error_mark_node)
errors = true;
@@ -4228,10 +4273,10 @@ build_vec_init (tree base, tree maxindex, tree init,
finish_expr_stmt (elt_init);
current_stmt_tree ()->stmts_are_full_exprs_p = 0;
- finish_expr_stmt (cp_build_unary_op (PREINCREMENT_EXPR, base, 0,
+ finish_expr_stmt (cp_build_unary_op (PREINCREMENT_EXPR, base, false,
complain));
if (base2)
- finish_expr_stmt (cp_build_unary_op (PREINCREMENT_EXPR, base2, 0,
+ finish_expr_stmt (cp_build_unary_op (PREINCREMENT_EXPR, base2, false,
complain));
finish_for_stmt (for_stmt);