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.

From-SVN: r240056
This commit is contained in:
Jason Merrill 2016-09-09 17:22:15 -04:00 committed by Jason Merrill
parent 51389084ec
commit af63ba4b30
39 changed files with 1043 additions and 62 deletions

View file

@ -1,3 +1,12 @@
2016-09-09 Jason Merrill <jason@redhat.com>
Implement C++17 new of over-aligned types.
* 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.
2016-09-09 Joseph Myers <joseph@codesourcery.com>
* c-cppbuiltin.c (builtin_define_type_width): New function.

View file

@ -12878,6 +12878,19 @@ scalar_to_vector (location_t loc, enum tree_code code, tree op0, tree op1,
return stv_nothing;
}
/* Return the alignment of std::max_align_t.
[support.types.layout] The type max_align_t is a POD type whose alignment
requirement is at least as great as that of every scalar type, and whose
alignment requirement is supported in every context. */
unsigned
max_align_t_align ()
{
return MAX (TYPE_ALIGN (long_long_integer_type_node),
TYPE_ALIGN (long_double_type_node));
}
/* Return true iff ALIGN is an integral constant that is a fundamental
alignment, as defined by [basic.align] in the c++-11
specifications.
@ -12886,14 +12899,12 @@ scalar_to_vector (location_t loc, enum tree_code code, tree op0, tree op1,
[A fundamental alignment is represented by an alignment less than or
equal to the greatest alignment supported by the implementation
in all contexts, which is equal to
alignof(max_align_t)]. */
in all contexts, which is equal to alignof(max_align_t)]. */
bool
cxx_fundamental_alignment_p (unsigned align)
cxx_fundamental_alignment_p (unsigned align)
{
return (align <= MAX (TYPE_ALIGN (long_long_integer_type_node),
TYPE_ALIGN (long_double_type_node)));
return (align <= max_align_t_align ());
}
/* Return true if T is a pointer to a zero-sized aggregate. */

View file

@ -863,6 +863,7 @@ extern bool keyword_begins_type_specifier (enum rid);
extern bool keyword_is_storage_class_specifier (enum rid);
extern bool keyword_is_type_qualifier (enum rid);
extern bool keyword_is_decl_specifier (enum rid);
extern unsigned max_align_t_align (void);
extern bool cxx_fundamental_alignment_p (unsigned);
extern bool pointer_to_zero_sized_aggr_p (tree);
extern bool diagnose_mismatched_attributes (tree, tree);

View file

@ -944,6 +944,12 @@ c_cpp_builtins (cpp_reader *pfile)
cpp_define (pfile, "__cpp_transactional_memory=210500");
if (flag_sized_deallocation)
cpp_define (pfile, "__cpp_sized_deallocation=201309");
if (aligned_new_threshhold)
{
cpp_define (pfile, "__cpp_aligned_new=201606");
cpp_define_formatted (pfile, "__STDCPP_DEFAULT_NEW_ALIGNMENT__=%d",
aligned_new_threshhold);
}
}
/* Note that we define this for C as well, so that we know if
__attribute__((cleanup)) will interface with EH. */

View file

@ -271,6 +271,26 @@ Waddress
C ObjC C++ ObjC++ Var(warn_address) Warning LangEnabledBy(C ObjC C++ ObjC++,Wall)
Warn about suspicious uses of memory addresses.
Enum
Name(warn_aligned_new_level) Type(int) UnknownError(argument %qs to %<-Waligned-new%> not recognized)
EnumValue
Enum(warn_aligned_new_level) String(none) Value(0)
EnumValue
Enum(warn_aligned_new_level) String(global) Value(1)
EnumValue
Enum(warn_aligned_new_level) String(all) Value(2)
Waligned-new
C++ ObjC++ Alias(Waligned-new=,global,none)
Warn about 'new' of type with extended alignment without -faligned-new.
Waligned-new=
C++ ObjC++ Var(warn_aligned_new) Enum(warn_aligned_new_level) Joined Warning LangEnabledBy(C++ ObjC++,Wall,1,0)
-Waligned-new=all Warn even if 'new' uses a class member allocation function.
Wall
C ObjC C++ ObjC++ Warning
Enable most warning messages.
@ -1032,6 +1052,14 @@ fada-spec-parent=
C ObjC C++ ObjC++ RejectNegative Joined Var(ada_specs_parent)
-fada-spec-parent=unit Dump Ada specs as child units of given parent.
faligned-new
C++ ObjC++ Alias(faligned-new=,1,0)
Support C++17 allocation of over-aligned types.
faligned-new=
C++ ObjC++ Joined Var(aligned_new_threshhold) UInteger Init(-1)
-faligned-new=<N> Use C++17 over-aligned type allocation for alignments greater than N.
fall-virtual
C++ ObjC++ Ignore Warn(switch %qs is no longer supported)

View file

@ -1,3 +1,18 @@
2016-09-09 Jason Merrill <jason@redhat.com>
Implement P0035R4, C++17 new of over-aligned types.
* 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.
2016-09-02 Jakub Jelinek <jakub@redhat.com>
PR sanitizer/77396

View file

@ -4211,13 +4211,14 @@ build_new_function_call (tree fn, vec<tree, va_gc> **args, bool koenig_p,
tree
build_operator_new_call (tree fnname, vec<tree, va_gc> **args,
tree *size, tree *cookie_size, tree size_check,
tree *size, tree *cookie_size,
tree align_arg, tree size_check,
tree *fn, tsubst_flags_t complain)
{
tree original_size = *size;
tree fns;
struct z_candidate *candidates;
struct z_candidate *cand;
struct z_candidate *cand = NULL;
bool any_viable_p;
if (fn)
@ -4247,9 +4248,20 @@ build_operator_new_call (tree fnname, vec<tree, va_gc> **args,
we disregard block-scope declarations of "operator new". */
fns = lookup_function_nonclass (fnname, *args, /*block_p=*/false);
if (align_arg)
{
vec<tree, va_gc>* align_args
= vec_copy_and_insert (*args, align_arg, 1);
cand = perform_overload_resolution (fns, align_args, &candidates,
&any_viable_p, tf_none);
/* If no aligned allocation function matches, try again without the
alignment. */
}
/* Figure out what function is being called. */
cand = perform_overload_resolution (fns, *args, &candidates, &any_viable_p,
complain);
if (!cand)
cand = perform_overload_resolution (fns, *args, &candidates, &any_viable_p,
complain);
/* If no suitable function could be found, issue an error message
and give up. */
@ -5945,16 +5957,65 @@ static bool
second_parm_is_size_t (tree fn)
{
tree t = FUNCTION_ARG_CHAIN (fn);
return (t
&& same_type_p (TREE_VALUE (t), size_type_node)
&& TREE_CHAIN (t) == void_list_node);
if (!t || !same_type_p (TREE_VALUE (t), size_type_node))
return false;
t = TREE_CHAIN (t);
if (t == void_list_node)
return true;
if (aligned_new_threshhold && t
&& same_type_p (TREE_VALUE (t), align_type_node)
&& TREE_CHAIN (t) == void_list_node)
return true;
return false;
}
/* True if T, an allocation function, has std::align_val_t as its second
argument. */
bool
aligned_allocation_fn_p (tree t)
{
if (!aligned_new_threshhold)
return false;
tree a = FUNCTION_ARG_CHAIN (t);
return (a && same_type_p (TREE_VALUE (a), align_type_node));
}
/* Returns true iff T, an element of an OVERLOAD chain, is a usual deallocation
function (3.7.4.2 [basic.stc.dynamic.deallocation]) with a parameter of
std::align_val_t. */
static bool
aligned_deallocation_fn_p (tree t)
{
if (!aligned_new_threshhold)
return false;
/* A template instance is never a usual deallocation function,
regardless of its signature. */
if (TREE_CODE (t) == TEMPLATE_DECL
|| primary_template_instantiation_p (t))
return false;
tree a = FUNCTION_ARG_CHAIN (t);
if (same_type_p (TREE_VALUE (a), align_type_node)
&& TREE_CHAIN (a) == void_list_node)
return true;
if (!same_type_p (TREE_VALUE (a), size_type_node))
return false;
a = TREE_CHAIN (a);
if (a && same_type_p (TREE_VALUE (a), align_type_node)
&& TREE_CHAIN (a) == void_list_node)
return true;
return false;
}
/* Returns true iff T, an element of an OVERLOAD chain, is a usual
deallocation function (3.7.4.2 [basic.stc.dynamic.deallocation]). */
bool
non_placement_deallocation_fn_p (tree t)
usual_deallocation_fn_p (tree t)
{
/* A template instance is never a usual deallocation function,
regardless of its signature. */
@ -5970,10 +6031,15 @@ non_placement_deallocation_fn_p (tree t)
of which has type std::size_t (18.2), then this function is a usual
deallocation function. */
bool global = DECL_NAMESPACE_SCOPE_P (t);
if (FUNCTION_ARG_CHAIN (t) == void_list_node
tree chain = FUNCTION_ARG_CHAIN (t);
if (!chain)
return false;
if (chain == void_list_node
|| ((!global || flag_sized_deallocation)
&& second_parm_is_size_t (t)))
return true;
if (aligned_deallocation_fn_p (t))
return true;
return false;
}
@ -6076,7 +6142,7 @@ build_op_delete_call (enum tree_code code, tree addr, tree size,
t; t = OVL_NEXT (t))
{
tree elt = OVL_CURRENT (t);
if (non_placement_deallocation_fn_p (elt)
if (usual_deallocation_fn_p (elt)
&& FUNCTION_ARG_CHAIN (elt) == void_list_node)
goto ok;
}
@ -6118,51 +6184,62 @@ build_op_delete_call (enum tree_code code, tree addr, tree size,
t; t = OVL_NEXT (t))
{
tree elt = OVL_CURRENT (t);
if (non_placement_deallocation_fn_p (elt))
if (usual_deallocation_fn_p (elt))
{
fn = elt;
/* "If a class T has a member deallocation function named
operator delete with exactly one parameter, then that
function is a usual (non-placement) deallocation
function. If class T does not declare such an operator
delete but does declare a member deallocation function named
operator delete with exactly two parameters, the second of
which has type std::size_t (18.2), then this function is a
usual deallocation function."
So in a class (void*) beats (void*, size_t). */
if (DECL_CLASS_SCOPE_P (fn))
if (!fn)
{
if (FUNCTION_ARG_CHAIN (fn) == void_list_node)
break;
fn = elt;
continue;
}
/* At global scope (in C++14 and above) the rules are different:
If deallocation function lookup finds both a usual
deallocation function with only a pointer parameter and a
usual deallocation function with both a pointer parameter
and a size parameter, the function to be called is selected
as follows:
/* -- If the type has new-extended alignment, a function with a
parameter of type std::align_val_t is preferred; otherwise a
function without such a parameter is preferred. If exactly one
preferred function is found, that function is selected and the
selection process terminates. If more than one preferred
function is found, all non-preferred functions are eliminated
from further consideration. */
if (aligned_new_threshhold)
{
bool want_align = type_has_new_extended_alignment (type);
bool fn_align = aligned_deallocation_fn_p (fn);
bool elt_align = aligned_deallocation_fn_p (elt);
* If the type is complete and if, for the second alternative
(delete array) only, the operand is a pointer to a class
type with a non-trivial destructor or a (possibly
multi-dimensional) array thereof, the function with two
parameters is selected.
if (elt_align != fn_align)
{
if (want_align == elt_align)
fn = elt;
continue;
}
}
* Otherwise, it is unspecified which of the two deallocation
functions is selected. */
/* -- If the deallocation functions have class scope, the one
without a parameter of type std::size_t is selected. */
bool want_size;
if (DECL_CLASS_SCOPE_P (fn))
want_size = false;
/* -- If the type is complete and if, for the second alternative
(delete array) only, the operand is a pointer to a class type
with a non-trivial destructor or a (possibly multi-dimensional)
array thereof, the function with a parameter of type std::size_t
is selected.
-- Otherwise, it is unspecified whether a deallocation function
with a parameter of type std::size_t is selected. */
else
{
bool want_size = COMPLETE_TYPE_P (type);
want_size = COMPLETE_TYPE_P (type);
if (code == VEC_DELETE_EXPR
&& !TYPE_VEC_NEW_USES_COOKIE (type))
/* We need a cookie to determine the array size. */
want_size = false;
bool have_size = (FUNCTION_ARG_CHAIN (fn) != void_list_node);
if (want_size == have_size)
break;
}
bool fn_size = second_parm_is_size_t (fn);
bool elt_size = second_parm_is_size_t (elt);
gcc_assert (fn_size != elt_size);
if (want_size == elt_size)
fn = elt;
}
}
@ -6200,8 +6277,13 @@ build_op_delete_call (enum tree_code code, tree addr, tree size,
tree ret;
vec<tree, va_gc> *args = make_tree_vector ();
args->quick_push (addr);
if (FUNCTION_ARG_CHAIN (fn) != void_list_node)
if (second_parm_is_size_t (fn))
args->quick_push (size);
if (aligned_deallocation_fn_p (fn))
{
tree al = build_int_cst (align_type_node, TYPE_ALIGN_UNIT (type));
args->quick_push (al);
}
ret = cp_build_function_call_vec (fn, &args, complain);
release_tree_vector (args);
return ret;

View file

@ -1147,6 +1147,8 @@ enum cp_tree_index
CPTI_NULLPTR,
CPTI_NULLPTR_TYPE,
CPTI_ALIGN_TYPE,
CPTI_MAX
};
@ -1182,6 +1184,8 @@ extern GTY(()) tree cp_global_trees[CPTI_MAX];
#define current_aggr cp_global_trees[CPTI_AGGR_TAG]
#define nullptr_node cp_global_trees[CPTI_NULLPTR]
#define nullptr_type_node cp_global_trees[CPTI_NULLPTR_TYPE]
/* std::align_val_t */
#define align_type_node cp_global_trees[CPTI_ALIGN_TYPE]
/* We cache these tree nodes so as to call get_identifier less
frequently. */
@ -5561,7 +5565,7 @@ extern tree build_user_type_conversion (tree, tree, int,
extern tree build_new_function_call (tree, vec<tree, va_gc> **, bool,
tsubst_flags_t);
extern tree build_operator_new_call (tree, vec<tree, va_gc> **, tree *,
tree *, tree, tree *,
tree *, tree, tree, tree *,
tsubst_flags_t);
extern tree build_new_method_call (tree, tree, vec<tree, va_gc> **,
tree, int, tree *,
@ -5573,7 +5577,8 @@ extern tree build_new_op (location_t, enum tree_code,
tsubst_flags_t);
extern tree build_op_call (tree, vec<tree, va_gc> **,
tsubst_flags_t);
extern bool non_placement_deallocation_fn_p (tree);
extern bool aligned_allocation_fn_p (tree);
extern bool usual_deallocation_fn_p (tree);
extern tree build_op_delete_call (enum tree_code, tree, tree,
bool, tree, tree,
tsubst_flags_t);
@ -5966,6 +5971,7 @@ extern tree get_nsdmi (tree, bool);
extern tree build_offset_ref (tree, tree, bool,
tsubst_flags_t);
extern tree throw_bad_array_new_length (void);
extern bool type_has_new_extended_alignment (tree);
extern tree build_new (vec<tree, va_gc> **, tree, tree,
vec<tree, va_gc> **, int,
tsubst_flags_t);
@ -6528,6 +6534,7 @@ extern tree build_min_nt_loc (location_t, enum tree_code,
extern tree build_min_non_dep (enum tree_code, tree, ...);
extern tree build_min_non_dep_op_overload (enum tree_code, tree, tree, ...);
extern tree build_min_non_dep_call_vec (tree, tree, vec<tree, va_gc> *);
extern vec<tree, va_gc>* vec_copy_and_insert (vec<tree, va_gc>*, tree, unsigned);
extern tree build_cplus_new (tree, tree, tsubst_flags_t);
extern tree build_aggr_init_expr (tree, tree);
extern tree get_target_expr (tree);

View file

@ -4132,6 +4132,17 @@ cxx_init_decl_processing (void)
/* Now, C++. */
current_lang_name = lang_name_cplusplus;
if (aligned_new_threshhold > 1
&& exact_log2 (aligned_new_threshhold) == -1)
{
error ("-faligned-new=%d is not a power of two", aligned_new_threshhold);
aligned_new_threshhold = 1;
}
if (aligned_new_threshhold == -1)
aligned_new_threshhold = (cxx_dialect >= cxx1z) ? 1 : 0;
if (aligned_new_threshhold == 1)
aligned_new_threshhold = max_align_t_align () / BITS_PER_UNIT;
{
tree newattrs, extvisattr;
tree newtype, deltype;
@ -4199,6 +4210,47 @@ cxx_init_decl_processing (void)
push_cp_library_fn (VEC_DELETE_EXPR, deltype, ECF_NOTHROW);
}
if (aligned_new_threshhold)
{
push_namespace (std_identifier);
tree align_id = get_identifier ("align_val_t");
align_type_node = start_enum (align_id, NULL_TREE, size_type_node,
NULL_TREE, /*scoped*/true, NULL);
pop_namespace ();
/* operator new (size_t, align_val_t); */
newtype = build_function_type_list (ptr_type_node, size_type_node,
align_type_node, NULL_TREE);
newtype = cp_build_type_attribute_variant (newtype, newattrs);
newtype = build_exception_variant (newtype, new_eh_spec);
opnew = push_cp_library_fn (NEW_EXPR, newtype, 0);
DECL_IS_MALLOC (opnew) = 1;
DECL_IS_OPERATOR_NEW (opnew) = 1;
opnew = push_cp_library_fn (VEC_NEW_EXPR, newtype, 0);
DECL_IS_MALLOC (opnew) = 1;
DECL_IS_OPERATOR_NEW (opnew) = 1;
/* operator delete (void *, align_val_t); */
deltype = build_function_type_list (void_type_node, ptr_type_node,
align_type_node, NULL_TREE);
deltype = cp_build_type_attribute_variant (deltype, extvisattr);
deltype = build_exception_variant (deltype, empty_except_spec);
push_cp_library_fn (DELETE_EXPR, deltype, ECF_NOTHROW);
push_cp_library_fn (VEC_DELETE_EXPR, deltype, ECF_NOTHROW);
if (flag_sized_deallocation)
{
/* operator delete (void *, size_t, align_val_t); */
deltype = build_function_type_list (void_type_node, ptr_type_node,
size_type_node, align_type_node,
NULL_TREE);
deltype = cp_build_type_attribute_variant (deltype, extvisattr);
deltype = build_exception_variant (deltype, empty_except_spec);
push_cp_library_fn (DELETE_EXPR, deltype, ECF_NOTHROW);
push_cp_library_fn (VEC_DELETE_EXPR, deltype, ECF_NOTHROW);
}
}
nullptr_type_node = make_node (NULLPTR_TYPE);
TYPE_SIZE (nullptr_type_node) = bitsize_int (GET_MODE_BITSIZE (ptr_mode));
TYPE_SIZE_UNIT (nullptr_type_node) = size_int (GET_MODE_SIZE (ptr_mode));

View file

@ -4488,7 +4488,7 @@ maybe_warn_sized_delete (enum tree_code code)
{
tree fn = OVL_CURRENT (ovl);
/* We're only interested in usual deallocation functions. */
if (!non_placement_deallocation_fn_p (fn))
if (!usual_deallocation_fn_p (fn))
continue;
if (FUNCTION_ARG_CHAIN (fn) == void_list_node)
unsized = fn;

View file

@ -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

View file

@ -2920,6 +2920,30 @@ build_min_non_dep_op_overload (enum tree_code op,
return call;
}
/* Return a new tree vec copied from VEC, with ELT inserted at index IDX. */
vec<tree, va_gc> *
vec_copy_and_insert (vec<tree, va_gc> *old_vec, tree elt, unsigned idx)
{
unsigned len = vec_safe_length (old_vec);
gcc_assert (idx <= len);
vec<tree, va_gc> *new_vec = NULL;
vec_alloc (new_vec, len + 1);
unsigned i;
for (i = 0; i < len; ++i)
{
if (i == idx)
new_vec->quick_push (elt);
new_vec->quick_push ((*old_vec)[i]);
}
if (i == idx)
new_vec->quick_push (elt);
return new_vec;
}
tree
get_type_decl (tree t)
{

View file

@ -190,7 +190,7 @@ in the following sections.
@item C++ Language Options
@xref{C++ Dialect Options,,Options Controlling C++ Dialect}.
@gccoptlist{-fabi-version=@var{n} -fno-access-control @gol
-fargs-in-order=@var{n} -fcheck-new @gol
-faligned-new=@var{n} -fargs-in-order=@var{n} -fcheck-new @gol
-fconstexpr-depth=@var{n} -fconstexpr-loop-limit=@var{n} @gol
-ffriend-injection @gol
-fno-elide-constructors @gol
@ -2237,6 +2237,15 @@ option is used for the warning.
Turn off all access checking. This switch is mainly useful for working
around bugs in the access control code.
@item -faligned-new
@opindex faligned-new
Enable support for C++17 @code{new} of types that require more
alignment than @code{void* ::operator new(std::size_t)} provides. A
numeric argument such as @code{-faligned-new=32} can be used to
specify how much alignment (in bytes) is provided by that function,
but few users will need to override the default of
@code{alignof(std::max_align_t)}.
@item -fcheck-new
@opindex fcheck-new
Check that the pointer returned by @code{operator new} is non-null
@ -5062,6 +5071,18 @@ disables the warnings about non-ISO @code{printf} / @code{scanf} format
width specifiers @code{I32}, @code{I64}, and @code{I} used on Windows targets,
which depend on the MS runtime.
@item -Waligned-new
@opindex Waligned-new
@opindex Wno-aligned-new
Warn about a new-expression of a type that requires greater alignment
than the @code{alignof(std::max_align_t)} but uses an allocation
function without an explicit alignment parameter. This option is
enabled by @option{-Wall}.
Normally this only warns about global allocation functions, but
@option{-Waligned-new=all} also warns about class member allocation
functions.
@item -Wplacement-new
@itemx -Wplacement-new=@var{n}
@opindex Wplacement-new

View file

@ -5,4 +5,4 @@
#include <new>
__attribute__((visibility("hidden")))void*operator new(std::size_t); // { dg-warning "visibility attribute ignored" }
// { dg-message "previous declaration" "" { target *-*-* } 116 }
// { dg-message "previous declaration" "" { target *-*-* } 120 }

View file

@ -0,0 +1,17 @@
// { dg-options -std=c++1z }
// { dg-do run }
#ifndef __STDCPP_DEFAULT_NEW_ALIGNMENT__
#error __STDCPP_DEFAULT_NEW_ALIGNMENT__ not defined
#endif
#include <cstdint>
struct alignas(64) A { int i; };
int main()
{
A *p = new A;
if (std::intptr_t(p) % 64 != 0)
__builtin_abort();
}

View file

@ -0,0 +1,31 @@
// { dg-options -std=c++1z }
// { dg-do run }
#include <new>
struct alignas(64) A {
int i;
A() { throw 42; }
};
struct B { int i; } b;
void *operator new (std::size_t s, std::align_val_t a, B b)
{
return operator new (s, a);
}
bool deleted = false;
void operator delete (void *p, std::align_val_t, B)
{
deleted = true;
}
int main()
{
try {
A *p = new (b) A;
__builtin_abort ();
} catch (...) {}
if (!deleted)
__builtin_abort ();
}

View file

@ -0,0 +1,23 @@
// { dg-options -std=c++1z }
// { dg-do run }
#include <new>
struct alignas(64) A {
int i;
};
bool deleted = false;
void operator delete (void *p, std::size_t, std::align_val_t)
{
deleted = true;
operator delete (p);
}
int main()
{
A *p = new A;
delete p;
if (!deleted)
__builtin_abort();
}

View file

@ -0,0 +1,13 @@
// { dg-options "-std=c++14 -Waligned-new" }
struct alignas(64) A { int i; };
struct alignas(64) B {
int i;
void *operator new(__SIZE_TYPE__);
};
int main()
{
A* ap = new A; // { dg-warning "-Waligned-new" }
B* bp = new B;
}

View file

@ -0,0 +1,13 @@
// { dg-options "-std=c++14 -Waligned-new=all" }
struct alignas(64) A { int i; };
struct alignas(64) B {
int i;
void *operator new(__SIZE_TYPE__);
};
int main()
{
A* ap = new A; // { dg-warning "-Waligned-new" }
B* bp = new B; // { dg-warning "-Waligned-new" }
}

View file

@ -0,0 +1,14 @@
// { dg-options -faligned-new }
// { dg-do run }
#include <new>
#include <stdint.h>
struct A { int i; };
int main()
{
A* ap = new (std::align_val_t(64)) A;
if (intptr_t(ap) % 64 != 0)
__builtin_abort();
}

View file

@ -350,6 +350,12 @@
# error "__cpp_if_constexpr != 201606"
#endif
#ifndef __cpp_aligned_new
# error "__cpp_aligned_new"
#elif __cpp_aligned_new != 201606
# error "__cpp_aligned_new != 201606"
#endif
#ifdef __has_cpp_attribute
# if ! __has_cpp_attribute(maybe_unused)

View file

@ -1,3 +1,22 @@
2016-09-09 Jason Merrill <jason@redhat.com>
Implement P0035R4, C++17 new of over-aligned types.
* 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.
2016-09-05 Tim Shen <timshen@google.com>
* include/std/variant: include bits/move.h for std::addressof.

View file

@ -6,6 +6,9 @@
/* Define to 1 if you have the `acosl' function. */
#undef HAVE_ACOSL
/* Define to 1 if you have the `aligned_alloc' function. */
#undef HAVE_ALIGNED_ALLOC
/* Define to 1 if you have the `asinf' function. */
#undef HAVE_ASINF
@ -285,6 +288,9 @@
/* Define if mbstate_t exists in wchar.h. */
#undef HAVE_MBSTATE_T
/* Define to 1 if you have the `memalign' function. */
#undef HAVE_MEMALIGN
/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H
@ -309,6 +315,9 @@
/* Define if poll is available in <poll.h>. */
#undef HAVE_POLL
/* Define to 1 if you have the `posix_memalign' function. */
#undef HAVE_POSIX_MEMALIGN
/* Define to 1 if you have the `powf' function. */
#undef HAVE_POWF
@ -505,6 +514,9 @@
/* Define to 1 if you have the `_acosl' function. */
#undef HAVE__ACOSL
/* Define to 1 if you have the `_aligned_malloc' function. */
#undef HAVE__ALIGNED_MALLOC
/* Define to 1 if you have the `_asinf' function. */
#undef HAVE__ASINF

View file

@ -2197,6 +2197,18 @@ CXXABI_1.3.11 {
__cxa_init_primary_exception;
_ZNSt15__exception_ptr13exception_ptrC1EPv;
# C++17 aligned new/delete
_ZnwmSt11align_val_t;
_ZnwmSt11align_val_tRKSt9nothrow_t;
_ZnamSt11align_val_t;
_ZnamSt11align_val_tRKSt9nothrow_t;
_ZdlPvSt11align_val_t;
_ZdlPvSt11align_val_tRKSt9nothrow_t;
_ZdlPvmSt11align_val_t;
_ZdaPvSt11align_val_t;
_ZdaPvSt11align_val_tRKSt9nothrow_t;
_ZdaPvmSt11align_val_t;
} CXXABI_1.3.10;
# Symbols in the support library (libsupc++) supporting transactional memory.

View file

@ -27969,6 +27969,19 @@ if test "x$ac_cv_func___cxa_thread_atexit_impl" = x""yes; then :
#define HAVE___CXA_THREAD_ATEXIT_IMPL 1
_ACEOF
fi
done
for ac_func in aligned_alloc posix_memalign memalign _aligned_malloc
do :
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
eval as_val=\$$as_ac_var
if test "x$as_val" = x""yes; then :
cat >>confdefs.h <<_ACEOF
#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
_ACEOF
fi
done

View file

@ -256,6 +256,7 @@ if $GLIBCXX_IS_NATIVE; then
GCC_CHECK_TLS
AC_CHECK_FUNCS(__cxa_thread_atexit_impl)
AC_CHECK_FUNCS(aligned_alloc posix_memalign memalign _aligned_malloc)
# For iconv support.
AM_ICONV

View file

@ -88,6 +88,16 @@ sources = \
new_opnt.cc \
new_opv.cc \
new_opvnt.cc \
new_opa.cc \
new_opant.cc \
new_opva.cc \
new_opvant.cc \
del_opa.cc \
del_opant.cc \
del_opsa.cc \
del_opva.cc \
del_opvant.cc \
del_opvsa.cc \
pbase_type_info.cc \
pmem_type_info.cc \
pointer_type_info.cc \
@ -189,6 +199,28 @@ del_opvs.lo: del_opvs.cc
del_opvs.o: del_opvs.cc
$(CXXCOMPILE) -std=gnu++14 -Wno-sized-deallocation -c $<
# Use special rules for the C++17 sources so that the proper flags are passed.
new_opa.lo: new_opa.cc
$(LTCXXCOMPILE) -std=gnu++1z -c $<
new_opant.lo: new_opant.cc
$(LTCXXCOMPILE) -std=gnu++1z -c $<
new_opva.lo: new_opva.cc
$(LTCXXCOMPILE) -std=gnu++1z -c $<
new_opvant.lo: new_opvant.cc
$(LTCXXCOMPILE) -std=gnu++1z -c $<
del_opa.lo: del_opa.cc
$(LTCXXCOMPILE) -std=gnu++1z -c $<
del_opant.lo: del_opant.cc
$(LTCXXCOMPILE) -std=gnu++1z -c $<
del_opsa.lo: del_opsa.cc
$(LTCXXCOMPILE) -std=gnu++1z -c $<
del_opva.lo: del_opva.cc
$(LTCXXCOMPILE) -std=gnu++1z -c $<
del_opvant.lo: del_opvant.cc
$(LTCXXCOMPILE) -std=gnu++1z -c $<
del_opvsa.lo: del_opvsa.cc
$(LTCXXCOMPILE) -std=gnu++1z -c $<
# AM_CXXFLAGS needs to be in each subdirectory so that it can be
# modified in a per-library or per-sub-library way. Need to manually
# set this option because CONFIG_CXXFLAGS has to be after

View file

@ -125,9 +125,11 @@ am__objects_1 = array_type_info.lo atexit_arm.lo atexit_thread.lo \
function_type_info.lo fundamental_type_info.lo guard.lo \
guard_error.lo hash_bytes.lo nested_exception.lo \
new_handler.lo new_op.lo new_opnt.lo new_opv.lo new_opvnt.lo \
pbase_type_info.lo pmem_type_info.lo pointer_type_info.lo \
pure.lo si_class_type_info.lo tinfo.lo tinfo2.lo vec.lo \
vmi_class_type_info.lo vterminate.lo
new_opa.lo new_opant.lo new_opva.lo new_opvant.lo del_opa.lo \
del_opant.lo del_opsa.lo del_opva.lo del_opvant.lo \
del_opvsa.lo pbase_type_info.lo pmem_type_info.lo \
pointer_type_info.lo pure.lo si_class_type_info.lo tinfo.lo \
tinfo2.lo vec.lo vmi_class_type_info.lo vterminate.lo
@GLIBCXX_HOSTED_TRUE@am__objects_2 = cp-demangle.lo
@ENABLE_VTABLE_VERIFY_TRUE@@VTV_CYGMIN_FALSE@am__objects_3 = \
@ENABLE_VTABLE_VERIFY_TRUE@@VTV_CYGMIN_FALSE@ vtv_stubs.lo
@ -445,6 +447,16 @@ sources = \
new_opnt.cc \
new_opv.cc \
new_opvnt.cc \
new_opa.cc \
new_opant.cc \
new_opva.cc \
new_opvant.cc \
del_opa.cc \
del_opant.cc \
del_opsa.cc \
del_opva.cc \
del_opvant.cc \
del_opvsa.cc \
pbase_type_info.cc \
pmem_type_info.cc \
pointer_type_info.cc \
@ -916,6 +928,28 @@ del_opvs.lo: del_opvs.cc
del_opvs.o: del_opvs.cc
$(CXXCOMPILE) -std=gnu++14 -Wno-sized-deallocation -c $<
# Use special rules for the C++17 sources so that the proper flags are passed.
new_opa.lo: new_opa.cc
$(LTCXXCOMPILE) -std=gnu++1z -c $<
new_opant.lo: new_opant.cc
$(LTCXXCOMPILE) -std=gnu++1z -c $<
new_opva.lo: new_opva.cc
$(LTCXXCOMPILE) -std=gnu++1z -c $<
new_opvant.lo: new_opvant.cc
$(LTCXXCOMPILE) -std=gnu++1z -c $<
del_opa.lo: del_opa.cc
$(LTCXXCOMPILE) -std=gnu++1z -c $<
del_opant.lo: del_opant.cc
$(LTCXXCOMPILE) -std=gnu++1z -c $<
del_opsa.lo: del_opsa.cc
$(LTCXXCOMPILE) -std=gnu++1z -c $<
del_opva.lo: del_opva.cc
$(LTCXXCOMPILE) -std=gnu++1z -c $<
del_opvant.lo: del_opvant.cc
$(LTCXXCOMPILE) -std=gnu++1z -c $<
del_opvsa.lo: del_opvsa.cc
$(LTCXXCOMPILE) -std=gnu++1z -c $<
install-stdHEADERS: $(std_HEADERS)
@$(NORMAL_INSTALL)
$(mkinstalldirs) $(DESTDIR)$(stddir)

View file

@ -0,0 +1,54 @@
// Boilerplate support routines for -*- C++ -*- dynamic memory management.
// Copyright (C) 1997-2016 Free Software Foundation, Inc.
//
// This file is part of GCC.
//
// GCC is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3, or (at your option)
// any later version.
//
// GCC is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
#include <bits/c++config.h>
#if !_GLIBCXX_HOSTED
// A freestanding C runtime may not provide "free" -- but there is no
// other reasonable way to implement "operator delete".
namespace std
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
extern "C" void free(void*);
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
#else
# include <cstdlib>
#endif
#include "new"
// The sized deletes are defined in other files.
#pragma GCC diagnostic ignored "-Wsized-deallocation"
_GLIBCXX_WEAK_DEFINITION void
operator delete(void* ptr, std::align_val_t) _GLIBCXX_USE_NOEXCEPT
{
#if !_GLIBCXX_HAVE_ALIGNED_ALLOC && _GLIBCXX_HAVE__ALIGNED_MALLOC
_aligned_free (ptr);
#else
std::free(ptr);
#endif
}

View file

@ -0,0 +1,33 @@
// Boilerplate support routines for -*- C++ -*- dynamic memory management.
// Copyright (C) 1997-2016 Free Software Foundation, Inc.
//
// This file is part of GCC.
//
// GCC is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3, or (at your option)
// any later version.
//
// GCC is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
#include <bits/c++config.h>
#include "new"
_GLIBCXX_WEAK_DEFINITION void
operator delete (void *ptr, std::align_val_t al, const std::nothrow_t&) _GLIBCXX_USE_NOEXCEPT
{
::operator delete (ptr, al);
}

View file

@ -0,0 +1,33 @@
// Boilerplate support routines for -*- C++ -*- dynamic memory management.
// Copyright (C) 1997-2016 Free Software Foundation, Inc.
//
// This file is part of GCC.
//
// GCC is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3, or (at your option)
// any later version.
//
// GCC is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
#include <bits/c++config.h>
#include "new"
_GLIBCXX_WEAK_DEFINITION void
operator delete(void* ptr, std::size_t, std::align_val_t al) _GLIBCXX_USE_NOEXCEPT
{
::operator delete (ptr, al);
}

View file

@ -0,0 +1,36 @@
// Boilerplate support routines for -*- C++ -*- dynamic memory management.
// Copyright (C) 1997-2016 Free Software Foundation, Inc.
//
// This file is part of GCC.
//
// GCC is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3, or (at your option)
// any later version.
//
// GCC is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
#include <bits/c++config.h>
#include "new"
// The sized deletes are defined in other files.
#pragma GCC diagnostic ignored "-Wsized-deallocation"
_GLIBCXX_WEAK_DEFINITION void
operator delete[] (void *ptr, std::align_val_t al) _GLIBCXX_USE_NOEXCEPT
{
::operator delete (ptr, al);
}

View file

@ -0,0 +1,33 @@
// Boilerplate support routines for -*- C++ -*- dynamic memory management.
// Copyright (C) 1997-2016 Free Software Foundation, Inc.
//
// This file is part of GCC.
//
// GCC is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3, or (at your option)
// any later version.
//
// GCC is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
#include <bits/c++config.h>
#include "new"
_GLIBCXX_WEAK_DEFINITION void
operator delete[] (void *ptr, std::align_val_t al, const std::nothrow_t&) _GLIBCXX_USE_NOEXCEPT
{
::operator delete[] (ptr, al);
}

View file

@ -0,0 +1,33 @@
// Boilerplate support routines for -*- C++ -*- dynamic memory management.
// Copyright (C) 1997-2016 Free Software Foundation, Inc.
//
// This file is part of GCC.
//
// GCC is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3, or (at your option)
// any later version.
//
// GCC is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
#include <bits/c++config.h>
#include "new"
_GLIBCXX_WEAK_DEFINITION void
operator delete[] (void *ptr, std::size_t, std::align_val_t al) _GLIBCXX_USE_NOEXCEPT
{
::operator delete[] (ptr, al);
}

View file

@ -79,6 +79,10 @@ namespace std
};
#endif
#if __cpp_aligned_new
enum class align_val_t: size_t {};
#endif
struct nothrow_t
{
#if __cplusplus >= 201103L
@ -135,6 +139,30 @@ void operator delete(void*, const std::nothrow_t&) _GLIBCXX_USE_NOEXCEPT
__attribute__((__externally_visible__));
void operator delete[](void*, const std::nothrow_t&) _GLIBCXX_USE_NOEXCEPT
__attribute__((__externally_visible__));
#if __cpp_aligned_new
void* operator new(std::size_t, std::align_val_t)
__attribute__((__externally_visible__));
void* operator new(std::size_t, std::align_val_t, const std::nothrow_t&)
_GLIBCXX_USE_NOEXCEPT __attribute__((__externally_visible__));
void operator delete(void*, std::align_val_t)
_GLIBCXX_USE_NOEXCEPT __attribute__((__externally_visible__));
void operator delete(void*, std::align_val_t, const std::nothrow_t&)
_GLIBCXX_USE_NOEXCEPT __attribute__((__externally_visible__));
void* operator new[](std::size_t, std::align_val_t)
__attribute__((__externally_visible__));
void* operator new[](std::size_t, std::align_val_t, const std::nothrow_t&)
_GLIBCXX_USE_NOEXCEPT __attribute__((__externally_visible__));
void operator delete[](void*, std::align_val_t)
_GLIBCXX_USE_NOEXCEPT __attribute__((__externally_visible__));
void operator delete[](void*, std::align_val_t, const std::nothrow_t&)
_GLIBCXX_USE_NOEXCEPT __attribute__((__externally_visible__));
#if __cpp_sized_deallocation
void operator delete(void*, std::size_t, std::align_val_t)
_GLIBCXX_USE_NOEXCEPT __attribute__((__externally_visible__));
void operator delete[](void*, std::size_t, std::align_val_t)
_GLIBCXX_USE_NOEXCEPT __attribute__((__externally_visible__));
#endif // __cpp_sized_deallocation
#endif // __cpp_aligned_new
// Default placement versions of operator new.
inline void* operator new(std::size_t, void* __p) _GLIBCXX_USE_NOEXCEPT

View file

@ -0,0 +1,76 @@
// Support routines for the -*- C++ -*- dynamic memory management.
// Copyright (C) 1997-2016 Free Software Foundation, Inc.
//
// This file is part of GCC.
//
// GCC is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3, or (at your option)
// any later version.
//
// GCC is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
#include <bits/c++config.h>
#include <stdlib.h>
#include <bits/exception_defines.h>
#include "new"
using std::new_handler;
using std::bad_alloc;
#if !_GLIBCXX_HAVE_ALIGNED_ALLOC
#if _GLIBCXX_HAVE__ALIGNED_MALLOC
#define aligned_alloc(al,sz) _aligned_malloc(sz,al)
#elif _GLIBCXX_HAVE_POSIX_MEMALIGN
static inline void*
aligned_alloc (std::size_t al, std::size_t sz)
{
void *ptr;
int ret = posix_memalign (&ptr, al, sz);
if (ret == 0)
return ptr;
return nullptr;
}
#elif _GLIBCXX_HAVE_MEMALIGN
#include <malloc.h>
#define aligned_alloc memalign
#else
// The C library doesn't provide any aligned allocation functions, declare
// aligned_alloc and get a link failure if aligned new is used.
extern "C" void *aligned_alloc(std::size_t, std::size_t);
#endif
#endif
_GLIBCXX_WEAK_DEFINITION void *
operator new (std::size_t sz, std::align_val_t al)
{
void *p;
/* malloc (0) is unpredictable; avoid it. */
if (sz == 0)
sz = 1;
while (__builtin_expect ((p = aligned_alloc ((std::size_t)al, sz)) == 0,
false))
{
new_handler handler = std::get_new_handler ();
if (! handler)
_GLIBCXX_THROW_OR_ABORT(bad_alloc());
handler ();
}
return p;
}

View file

@ -0,0 +1,41 @@
// Boilerplate support routines for -*- C++ -*- dynamic memory management.
// Copyright (C) 1997-2016 Free Software Foundation, Inc.
//
// This file is part of GCC.
//
// GCC is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3, or (at your option)
// any later version.
//
// GCC is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
#include <bits/c++config.h>
#include "new"
_GLIBCXX_WEAK_DEFINITION void*
operator new(std::size_t sz, std::align_val_t al, const std::nothrow_t&)
_GLIBCXX_USE_NOEXCEPT
{
__try
{
return operator new(sz, al);
}
__catch(...)
{
return 0;
}
}

View file

@ -0,0 +1,33 @@
// Boilerplate support routines for -*- C++ -*- dynamic memory management.
// Copyright (C) 1997-2016 Free Software Foundation, Inc.
//
// This file is part of GCC.
//
// GCC is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3, or (at your option)
// any later version.
//
// GCC is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
#include <bits/c++config.h>
#include "new"
_GLIBCXX_WEAK_DEFINITION void*
operator new[] (std::size_t sz, std::align_val_t al)
{
return ::operator new(sz, al);
}

View file

@ -0,0 +1,41 @@
// Boilerplate support routines for -*- C++ -*- dynamic memory management.
// Copyright (C) 1997-2016 Free Software Foundation, Inc.
//
// This file is part of GCC.
//
// GCC is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3, or (at your option)
// any later version.
//
// GCC is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
#include <bits/c++config.h>
#include "new"
_GLIBCXX_WEAK_DEFINITION void*
operator new[] (std::size_t sz, std::align_val_t al, const std::nothrow_t&)
_GLIBCXX_USE_NOEXCEPT
{
__try
{
return ::operator new[](sz, al);
}
__catch(...)
{
return 0;
}
}