diff options
author | jason <jason@138bc75d-0d04-0410-961f-82ee72b054a4> | 2016-09-09 21:22:15 +0000 |
---|---|---|
committer | jason <jason@138bc75d-0d04-0410-961f-82ee72b054a4> | 2016-09-09 21:22:15 +0000 |
commit | db8ffb402adef529e224cdc4bd73e09a3aa247f2 (patch) | |
tree | 9648be877d043d0cd4ebb37ef5b0e82da08fd4f0 /gcc/cp/init.c | |
parent | 8e84d0a7e2abaf4ca9aea3670f9be9271950f257 (diff) | |
download | gcc-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.c | 56 |
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 |