aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/c-family/ChangeLog9
-rw-r--r--gcc/c-family/c-common.c21
-rw-r--r--gcc/c-family/c-common.h1
-rw-r--r--gcc/c-family/c-cppbuiltin.c6
-rw-r--r--gcc/c-family/c.opt28
-rw-r--r--gcc/cp/ChangeLog15
-rw-r--r--gcc/cp/call.c174
-rw-r--r--gcc/cp/cp-tree.h11
-rw-r--r--gcc/cp/decl.c52
-rw-r--r--gcc/cp/decl2.c2
-rw-r--r--gcc/cp/init.c56
-rw-r--r--gcc/cp/tree.c24
-rw-r--r--gcc/doc/invoke.texi23
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/Wattributes1.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp1z/aligned-new1.C17
-rw-r--r--gcc/testsuite/g++.dg/cpp1z/aligned-new2.C31
-rw-r--r--gcc/testsuite/g++.dg/cpp1z/aligned-new3.C23
-rw-r--r--gcc/testsuite/g++.dg/cpp1z/aligned-new4.C13
-rw-r--r--gcc/testsuite/g++.dg/cpp1z/aligned-new4a.C13
-rw-r--r--gcc/testsuite/g++.dg/cpp1z/aligned-new5.C14
-rw-r--r--gcc/testsuite/g++.dg/cpp1z/feat-cxx1z.C6
-rw-r--r--libstdc++-v3/ChangeLog19
-rw-r--r--libstdc++-v3/config.h.in12
-rw-r--r--libstdc++-v3/config/abi/pre/gnu.ver12
-rwxr-xr-xlibstdc++-v3/configure13
-rw-r--r--libstdc++-v3/configure.ac1
-rw-r--r--libstdc++-v3/libsupc++/Makefile.am32
-rw-r--r--libstdc++-v3/libsupc++/Makefile.in40
-rw-r--r--libstdc++-v3/libsupc++/del_opa.cc54
-rw-r--r--libstdc++-v3/libsupc++/del_opant.cc33
-rw-r--r--libstdc++-v3/libsupc++/del_opsa.cc33
-rw-r--r--libstdc++-v3/libsupc++/del_opva.cc36
-rw-r--r--libstdc++-v3/libsupc++/del_opvant.cc33
-rw-r--r--libstdc++-v3/libsupc++/del_opvsa.cc33
-rw-r--r--libstdc++-v3/libsupc++/new28
-rw-r--r--libstdc++-v3/libsupc++/new_opa.cc76
-rw-r--r--libstdc++-v3/libsupc++/new_opant.cc41
-rw-r--r--libstdc++-v3/libsupc++/new_opva.cc33
-rw-r--r--libstdc++-v3/libsupc++/new_opvant.cc41
39 files changed, 1046 insertions, 65 deletions
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog
index 331be69..ba89248 100644
--- a/gcc/c-family/ChangeLog
+++ b/gcc/c-family/ChangeLog
@@ -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.
diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index 656f639..9a66cfe 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -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. */
diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
index 1d923c9..2e211c4 100644
--- a/gcc/c-family/c-common.h
+++ b/gcc/c-family/c-common.h
@@ -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);
diff --git a/gcc/c-family/c-cppbuiltin.c b/gcc/c-family/c-cppbuiltin.c
index 3338276..bb30829 100644
--- a/gcc/c-family/c-cppbuiltin.c
+++ b/gcc/c-family/c-cppbuiltin.c
@@ -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. */
diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt
index a5358ed..c55c7c3 100644
--- a/gcc/c-family/c.opt
+++ b/gcc/c-family/c.opt
@@ -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)
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index a3f51bb..9480993 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 024519d..167d778 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -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 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.
-
- * Otherwise, it is unspecified which of the two deallocation
- functions is selected. */
+
+ /* -- 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 (elt_align != fn_align)
+ {
+ if (want_align == elt_align)
+ fn = elt;
+ continue;
+ }
+ }
+
+ /* -- 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;
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 5bcb98b..d4bfb26 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -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);
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 43cf3df..9d91387 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -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));
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index 2ba5ffb..a320f92 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -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;
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index 1a5766a..5bb7f29 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
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index 6d254dd..bd2e8f6 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -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)
{
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 20be9b7..b2eaea7 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -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
diff --git a/gcc/testsuite/g++.dg/cpp0x/Wattributes1.C b/gcc/testsuite/g++.dg/cpp0x/Wattributes1.C
index dd9011b..b0a1e86 100644
--- a/gcc/testsuite/g++.dg/cpp0x/Wattributes1.C
+++ b/gcc/testsuite/g++.dg/cpp0x/Wattributes1.C
@@ -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 }
diff --git a/gcc/testsuite/g++.dg/cpp1z/aligned-new1.C b/gcc/testsuite/g++.dg/cpp1z/aligned-new1.C
new file mode 100644
index 0000000..735296f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1z/aligned-new1.C
@@ -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();
+}
diff --git a/gcc/testsuite/g++.dg/cpp1z/aligned-new2.C b/gcc/testsuite/g++.dg/cpp1z/aligned-new2.C
new file mode 100644
index 0000000..fe15969
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1z/aligned-new2.C
@@ -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 ();
+}
diff --git a/gcc/testsuite/g++.dg/cpp1z/aligned-new3.C b/gcc/testsuite/g++.dg/cpp1z/aligned-new3.C
new file mode 100644
index 0000000..73e3343
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1z/aligned-new3.C
@@ -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();
+}
diff --git a/gcc/testsuite/g++.dg/cpp1z/aligned-new4.C b/gcc/testsuite/g++.dg/cpp1z/aligned-new4.C
new file mode 100644
index 0000000..cc63a14
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1z/aligned-new4.C
@@ -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;
+}
diff --git a/gcc/testsuite/g++.dg/cpp1z/aligned-new4a.C b/gcc/testsuite/g++.dg/cpp1z/aligned-new4a.C
new file mode 100644
index 0000000..eb178d4
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1z/aligned-new4a.C
@@ -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" }
+}
diff --git a/gcc/testsuite/g++.dg/cpp1z/aligned-new5.C b/gcc/testsuite/g++.dg/cpp1z/aligned-new5.C
new file mode 100644
index 0000000..525129e
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1z/aligned-new5.C
@@ -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();
+}
diff --git a/gcc/testsuite/g++.dg/cpp1z/feat-cxx1z.C b/gcc/testsuite/g++.dg/cpp1z/feat-cxx1z.C
index 41b6111..982572e 100644
--- a/gcc/testsuite/g++.dg/cpp1z/feat-cxx1z.C
+++ b/gcc/testsuite/g++.dg/cpp1z/feat-cxx1z.C
@@ -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)
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 517db56..4ba6593 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -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.
diff --git a/libstdc++-v3/config.h.in b/libstdc++-v3/config.h.in
index 5ac2df4..2ab6e0d 100644
--- a/libstdc++-v3/config.h.in
+++ b/libstdc++-v3/config.h.in
@@ -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
diff --git a/libstdc++-v3/config/abi/pre/gnu.ver b/libstdc++-v3/config/abi/pre/gnu.ver
index 0ab4bb1..9b5bb23 100644
--- a/libstdc++-v3/config/abi/pre/gnu.ver
+++ b/libstdc++-v3/config/abi/pre/gnu.ver
@@ -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.
diff --git a/libstdc++-v3/configure b/libstdc++-v3/configure
index bfcb465..6332c4d 100755
--- a/libstdc++-v3/configure
+++ b/libstdc++-v3/configure
@@ -27972,6 +27972,19 @@ _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
+
# For iconv support.
diff --git a/libstdc++-v3/configure.ac b/libstdc++-v3/configure.ac
index 9e19e99..5657ecb 100644
--- a/libstdc++-v3/configure.ac
+++ b/libstdc++-v3/configure.ac
@@ -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
diff --git a/libstdc++-v3/libsupc++/Makefile.am b/libstdc++-v3/libsupc++/Makefile.am
index ba4eac1..2df31ff 100644
--- a/libstdc++-v3/libsupc++/Makefile.am
+++ b/libstdc++-v3/libsupc++/Makefile.am
@@ -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
diff --git a/libstdc++-v3/libsupc++/Makefile.in b/libstdc++-v3/libsupc++/Makefile.in
index 3fb9d16..e828ed9 100644
--- a/libstdc++-v3/libsupc++/Makefile.in
+++ b/libstdc++-v3/libsupc++/Makefile.in
@@ -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)
diff --git a/libstdc++-v3/libsupc++/del_opa.cc b/libstdc++-v3/libsupc++/del_opa.cc
new file mode 100644
index 0000000..889bdb7
--- /dev/null
+++ b/libstdc++-v3/libsupc++/del_opa.cc
@@ -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
+}
diff --git a/libstdc++-v3/libsupc++/del_opant.cc b/libstdc++-v3/libsupc++/del_opant.cc
new file mode 100644
index 0000000..1b1919c
--- /dev/null
+++ b/libstdc++-v3/libsupc++/del_opant.cc
@@ -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);
+}
diff --git a/libstdc++-v3/libsupc++/del_opsa.cc b/libstdc++-v3/libsupc++/del_opsa.cc
new file mode 100644
index 0000000..7880efe
--- /dev/null
+++ b/libstdc++-v3/libsupc++/del_opsa.cc
@@ -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);
+}
diff --git a/libstdc++-v3/libsupc++/del_opva.cc b/libstdc++-v3/libsupc++/del_opva.cc
new file mode 100644
index 0000000..95d2a3f
--- /dev/null
+++ b/libstdc++-v3/libsupc++/del_opva.cc
@@ -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);
+}
diff --git a/libstdc++-v3/libsupc++/del_opvant.cc b/libstdc++-v3/libsupc++/del_opvant.cc
new file mode 100644
index 0000000..5840c8f
--- /dev/null
+++ b/libstdc++-v3/libsupc++/del_opvant.cc
@@ -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);
+}
diff --git a/libstdc++-v3/libsupc++/del_opvsa.cc b/libstdc++-v3/libsupc++/del_opvsa.cc
new file mode 100644
index 0000000..61586b0
--- /dev/null
+++ b/libstdc++-v3/libsupc++/del_opvsa.cc
@@ -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);
+}
diff --git a/libstdc++-v3/libsupc++/new b/libstdc++-v3/libsupc++/new
index 8e8a327..477fadc 100644
--- a/libstdc++-v3/libsupc++/new
+++ b/libstdc++-v3/libsupc++/new
@@ -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
diff --git a/libstdc++-v3/libsupc++/new_opa.cc b/libstdc++-v3/libsupc++/new_opa.cc
new file mode 100644
index 0000000..6ff5421
--- /dev/null
+++ b/libstdc++-v3/libsupc++/new_opa.cc
@@ -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;
+}
diff --git a/libstdc++-v3/libsupc++/new_opant.cc b/libstdc++-v3/libsupc++/new_opant.cc
new file mode 100644
index 0000000..c863d64
--- /dev/null
+++ b/libstdc++-v3/libsupc++/new_opant.cc
@@ -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;
+ }
+}
diff --git a/libstdc++-v3/libsupc++/new_opva.cc b/libstdc++-v3/libsupc++/new_opva.cc
new file mode 100644
index 0000000..7109431
--- /dev/null
+++ b/libstdc++-v3/libsupc++/new_opva.cc
@@ -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);
+}
diff --git a/libstdc++-v3/libsupc++/new_opvant.cc b/libstdc++-v3/libsupc++/new_opvant.cc
new file mode 100644
index 0000000..a32fec8
--- /dev/null
+++ b/libstdc++-v3/libsupc++/new_opvant.cc
@@ -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;
+ }
+}