summaryrefslogtreecommitdiff
path: root/gcc/cp/init.c
diff options
context:
space:
mode:
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>2016-09-09 21:22:15 +0000
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>2016-09-09 21:22:15 +0000
commitdb8ffb402adef529e224cdc4bd73e09a3aa247f2 (patch)
tree9648be877d043d0cd4ebb37ef5b0e82da08fd4f0 /gcc/cp/init.c
parent8e84d0a7e2abaf4ca9aea3670f9be9271950f257 (diff)
downloadgcc-db8ffb402adef529e224cdc4bd73e09a3aa247f2.tar.gz
Implement P0035R4, C++17 new of over-aligned types.
gcc/cp/ * cp-tree.h (enum cp_tree_index): Add CPTI_ALIGN_TYPE. (align_type_node): New macro. * call.c (build_operator_new_call): Handle C++17 aligned new. (second_parm_is_size_t, build_op_delete_call): Likewise. (non_placement_deallocation_fn_p): Likewise. Rename to usual_deallocation_fn_p. (aligned_allocation_fn_p, aligned_deallocation_fn_p): New. * decl.c (cxx_init_decl_processing): Add aligned new support. * init.c (type_has_new_extended_alignment): New. (build_new_1): Handle aligned new. * tree.c (vec_copy_and_insert): New. gcc/c-family/ * c.opt: Add -faligned-new and -Waligned-new. * c-common.c (max_align_t_align): Split out from... (cxx_fundamental_alignment_p): ...here. * c-common.h: Declare it. * c-cppbuiltin.c (c_cpp_builtins): Handle aligned new. libstdc++-v3/ * libsupc++/new: Declare aligned new/delete operators. * config/abi/pre/gnu.ver: Export them. * configure.ac: Check for aligned_alloc, posix_memalign, memalign, _aligned_malloc. * libsupc++/new_opa.cc: New. * libsupc++/new_opant.cc: New. * libsupc++/new_opva.cc: New. * libsupc++/new_opva.cc: New. * libsupc++/del_opa.cc: New. * libsupc++/del_opant.cc: New. * libsupc++/del_opsa.cc: New. * libsupc++/del_opva.cc: New. * libsupc++/del_opvant.cc: New. * libsupc++/del_opvsa.cc: New. * libsupc++/Makefile.am: Build them. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@240056 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/cp/init.c')
-rw-r--r--gcc/cp/init.c56
1 files changed, 50 insertions, 6 deletions
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index 1a5766a42b7..5bb7f291117 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