public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* RFA (libstdc++): PATCH to implement C++17 over-aligned new
@ 2016-09-08  7:10 Jason Merrill
  2016-09-08  8:32 ` Marc Glisse
                   ` (2 more replies)
  0 siblings, 3 replies; 42+ messages in thread
From: Jason Merrill @ 2016-09-08  7:10 UTC (permalink / raw)
  To: gcc-patches List, libstdc++, Joseph S. Myers

[-- Attachment #1: Type: text/plain, Size: 932 bytes --]

This patch adds support for C++17 allocation of types with alignment
greater than max_align_t using 'new'.  This is on by default in C++17
and can also be enabled for other -std= with -falign-new.

If a user wants to use a different boundary than alignof(max_align_t),
perhaps because their malloc provides more or less alignment than
glibc's, they can specify -falign-new=<N>.

The patch also adds a warning about allocating an over-aligned type
without using an aligned new-operator, which is enabled by -Wall.

libstdc++ folk: Does my configury handling of different C library
functions that might be usable for aligned allocation make sense?  Is
the (standard-conforming) implementation of the nothrow allocation
function OK despite Jonathan's comment in bug 68210?  OK for trunk?

Joseph: My introduction of max_align_t_align will need to be merged
with your change to cxx_fundamental_alignment_p.

Tested x86_64-pc-linux-gnu.

[-- Attachment #2: aligned-new.diff --]
[-- Type: text/plain, Size: 55538 bytes --]

commit bea7a322a3b2badc3e80bddee7d5e6b20f4c2fe0
Author: Jason Merrill <jason@redhat.com>
Date:   Wed Sep 7 16:22:54 2016 -0400

            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.
            * 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.

diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index de9f881..12d0e18 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -12875,6 +12875,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.
@@ -12883,14 +12896,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 42ce969..baacb6c 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 ee4d233..ea34187 100644
--- a/gcc/c-family/c-cppbuiltin.c
+++ b/gcc/c-family/c-cppbuiltin.c
@@ -906,6 +906,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/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."
+	    if (!fn)
+	      {
+		fn = elt;
+		continue;
+	      }
 
-	       So in a class (void*) beats (void*, size_t).  */
+	    /* -- 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))
-	      {
-		if (FUNCTION_ARG_CHAIN (fn) == void_list_node)
-		  break;
-	      }
-	    /* At global scope (in C++14 and above) the rules are different:
+	      want_size = false;
 
-	       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 a parameter of type std::size_t
+	       is selected.
 
-	       * 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. */
+	       -- 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..2f44465 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
+      && !pow2p_hwi (aligned_new_threshhold))
+    {
+      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/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..f9bb752 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
+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..6a64d88 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)
 
   # 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..24dec22
--- /dev/null
+++ b/libstdc++-v3/libsupc++/del_opa.cc
@@ -0,0 +1,50 @@
+// 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
+{
+  std::free(ptr);
+}
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..21940e8
--- /dev/null
+++ b/libstdc++-v3/libsupc++/new_opa.cc
@@ -0,0 +1,74 @@
+// 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 !HAVE_ALIGNED_ALLOC
+#if 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 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;
+    }
+}

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: RFA (libstdc++): PATCH to implement C++17 over-aligned new
  2016-09-08  7:10 RFA (libstdc++): PATCH to implement C++17 over-aligned new Jason Merrill
@ 2016-09-08  8:32 ` Marc Glisse
  2016-09-08 11:18   ` Jonathan Wakely
  2016-09-08 11:00 ` Jonathan Wakely
  2017-11-24 14:26 ` Marc Glisse
  2 siblings, 1 reply; 42+ messages in thread
From: Marc Glisse @ 2016-09-08  8:32 UTC (permalink / raw)
  To: Jason Merrill; +Cc: gcc-patches List, libstdc++, Joseph S. Myers

On Thu, 8 Sep 2016, Jason Merrill wrote:

> This patch adds support for C++17 allocation of types with alignment
> greater than max_align_t using 'new'.  This is on by default in C++17
> and can also be enabled for other -std= with -falign-new.

Great :-)

> If a user wants to use a different boundary than alignof(max_align_t),
> perhaps because their malloc provides more or less alignment than
> glibc's, they can specify -falign-new=<N>.
>
> The patch also adds a warning about allocating an over-aligned type
> without using an aligned new-operator, which is enabled by -Wall.
>
> libstdc++ folk: Does my configury handling of different C library
> functions that might be usable for aligned allocation make sense?  Is
> the (standard-conforming) implementation of the nothrow allocation
> function OK despite Jonathan's comment in bug 68210?  OK for trunk?

Do we want a generic fallback implementation (similar to 
gcc/config/i386/gmm_malloc.h)? A windows version with _aligned_malloc / 
_aligned_free would also be possible.

-- 
Marc Glisse

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: RFA (libstdc++): PATCH to implement C++17 over-aligned new
  2016-09-08  7:10 RFA (libstdc++): PATCH to implement C++17 over-aligned new Jason Merrill
  2016-09-08  8:32 ` Marc Glisse
@ 2016-09-08 11:00 ` Jonathan Wakely
  2017-11-24 14:26 ` Marc Glisse
  2 siblings, 0 replies; 42+ messages in thread
From: Jonathan Wakely @ 2016-09-08 11:00 UTC (permalink / raw)
  To: Jason Merrill; +Cc: gcc-patches List, libstdc++, Joseph S. Myers

On 08/09/16 02:06 -0400, Jason Merrill wrote:
>This patch adds support for C++17 allocation of types with alignment
>greater than max_align_t using 'new'.  This is on by default in C++17
>and can also be enabled for other -std= with -falign-new.

Nice.

>If a user wants to use a different boundary than alignof(max_align_t),
>perhaps because their malloc provides more or less alignment than
>glibc's, they can specify -falign-new=<N>.
>
>The patch also adds a warning about allocating an over-aligned type
>without using an aligned new-operator, which is enabled by -Wall.
>
>libstdc++ folk: Does my configury handling of different C library
>functions that might be usable for aligned allocation make sense?

The AC_CHECK_FUNCS is OK but our configure munges all the autoconf
macros to add _GLIBCXX_ as a prefix, so you need to check
_GLIBCXX_HAVE_ALIGNED_ALLOC not HAVE_ALIGNED_ALLOC, and similarly for
the other two macros. Otherwise you always get this case:

+// 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);

So it will fail for a pre-C11 libc even if it provides posix_memalign.

>Is
>the (standard-conforming) implementation of the nothrow allocation
>function OK despite Jonathan's comment in bug 68210?

Yes. If anyone (maybe Taller Technologies?) cares about building
libstdc++ with -fno-exceptions then they can patch the new_op*.cc
files to do something different when !defined(__cpp_exceptions).
Or maybe I'll look at doing that as part of fixing 68210.

I'm still a little bothered about the try-catch overhead being
incurred for the std::nothrow_t allocation functions, but assuming
that allocation failure is rare that won't usually be a problem.

>OK for trunk?

The libstdc++ parts are OK with the s/HAVE/_GLIBCXX_HAVE/ change.

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: RFA (libstdc++): PATCH to implement C++17 over-aligned new
  2016-09-08  8:32 ` Marc Glisse
@ 2016-09-08 11:18   ` Jonathan Wakely
  2016-09-09 21:40     ` Jason Merrill
  0 siblings, 1 reply; 42+ messages in thread
From: Jonathan Wakely @ 2016-09-08 11:18 UTC (permalink / raw)
  To: libstdc++; +Cc: Jason Merrill, gcc-patches List, Joseph S. Myers

On 08/09/16 09:10 +0200, Marc Glisse wrote:
>Do we want a generic fallback implementation (similar to 
>gcc/config/i386/gmm_malloc.h)? A windows version with _aligned_malloc 
>/ _aligned_free would also be possible.

Making it work for MinGW would be nice. If there are other targets
that don't support any of C11, POSIX-2001, or memalign then we can add
a generic fallback later, but I'm not sure it's worth doing now. It
might never be needed.

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: RFA (libstdc++): PATCH to implement C++17 over-aligned new
  2016-09-08 11:18   ` Jonathan Wakely
@ 2016-09-09 21:40     ` Jason Merrill
  2016-09-10  7:03       ` Christophe Lyon
                         ` (3 more replies)
  0 siblings, 4 replies; 42+ messages in thread
From: Jason Merrill @ 2016-09-09 21:40 UTC (permalink / raw)
  To: Jonathan Wakely; +Cc: libstdc++, gcc-patches List

[-- Attachment #1: Type: text/plain, Size: 419 bytes --]

On Thu, Sep 8, 2016 at 7:06 AM, Jonathan Wakely <jwakely@redhat.com> wrote:
> On 08/09/16 09:10 +0200, Marc Glisse wrote:
>>
>> Do we want a generic fallback implementation (similar to
>> gcc/config/i386/gmm_malloc.h)? A windows version with _aligned_malloc /
>> _aligned_free would also be possible.
>
> Making it work for MinGW would be nice.

OK, this is what I'm checking in; could someone test it on MinGW?

Jason

[-- Attachment #2: aligned-new.diff --]
[-- Type: text/plain, Size: 57011 bytes --]

commit a528da2f1cabfcfd127e3246342dab2271254e45
Author: Jason Merrill <jason@redhat.com>
Date:   Wed Sep 7 16:22:54 2016 -0400

            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.

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/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."
+	    if (!fn)
+	      {
+		fn = elt;
+		continue;
+	      }
 
-	       So in a class (void*) beats (void*, size_t).  */
+	    /* -- 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))
-	      {
-		if (FUNCTION_ARG_CHAIN (fn) == void_list_node)
-		  break;
-	      }
-	    /* At global scope (in C++14 and above) the rules are different:
+	      want_size = false;
 
-	       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 a parameter of type std::size_t
+	       is selected.
 
-	       * 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. */
+	       -- 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/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;
+    }
+}

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: RFA (libstdc++): PATCH to implement C++17 over-aligned new
  2016-09-09 21:40     ` Jason Merrill
@ 2016-09-10  7:03       ` Christophe Lyon
  2016-09-10 10:14         ` Marc Glisse
                           ` (2 more replies)
  2016-09-10 10:14       ` Jonathan Wakely
                         ` (2 subsequent siblings)
  3 siblings, 3 replies; 42+ messages in thread
From: Christophe Lyon @ 2016-09-10  7:03 UTC (permalink / raw)
  To: Jason Merrill; +Cc: Jonathan Wakely, libstdc++, gcc-patches List

On 9 September 2016 at 23:20, Jason Merrill <jason@redhat.com> wrote:
> On Thu, Sep 8, 2016 at 7:06 AM, Jonathan Wakely <jwakely@redhat.com> wrote:
>> On 08/09/16 09:10 +0200, Marc Glisse wrote:
>>>
>>> Do we want a generic fallback implementation (similar to
>>> gcc/config/i386/gmm_malloc.h)? A windows version with _aligned_malloc /
>>> _aligned_free would also be possible.
>>
>> Making it work for MinGW would be nice.
>
> OK, this is what I'm checking in; could someone test it on MinGW?
>
> Jason

Hi Jason,

I'm seeing problems on arm*linux: the tests aligned-new[1235].C fail to link:
aligned-new5.C:(.text+0x14): undefined reference to `operator
new(unsigned int, std::align_val_t)'


On aarch64*-elf and arm-eabi (using newlib), I'm seeing:
/gccsrc/libstdc++-v3/libsupc++/new_opa.cc:66: undefined reference to
`aligned_alloc'

Am I missing something in my setup?

Thanks,

Christophe

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: RFA (libstdc++): PATCH to implement C++17 over-aligned new
  2016-09-09 21:40     ` Jason Merrill
  2016-09-10  7:03       ` Christophe Lyon
@ 2016-09-10 10:14       ` Jonathan Wakely
  2016-09-11  7:09       ` Andreas Schwab
  2016-09-12 14:15       ` Rainer Orth
  3 siblings, 0 replies; 42+ messages in thread
From: Jonathan Wakely @ 2016-09-10 10:14 UTC (permalink / raw)
  To: Jason Merrill; +Cc: libstdc++, gcc-patches List

On 09/09/16 17:20 -0400, Jason Merrill wrote:
>OK, this is what I'm checking in; could someone test it on MinGW?

MSDN suggests we need <malloc.h> for _aligned_malloc, but I'm not
sure. Last time I tried to build and test MinGW it made me cry, and I
no longer have any access to Windows machines anyway.

But rather than trying to fix it blind let's wait for feedback and see
if it works for MinGW or not.

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: RFA (libstdc++): PATCH to implement C++17 over-aligned new
  2016-09-10  7:03       ` Christophe Lyon
@ 2016-09-10 10:14         ` Marc Glisse
  2016-09-10 10:35           ` Jonathan Wakely
  2016-09-11  9:14         ` Christophe Lyon
  2016-09-13 13:04         ` Szabolcs Nagy
  2 siblings, 1 reply; 42+ messages in thread
From: Marc Glisse @ 2016-09-10 10:14 UTC (permalink / raw)
  To: Christophe Lyon
  Cc: Jason Merrill, Jonathan Wakely, libstdc++, gcc-patches List

On Sat, 10 Sep 2016, Christophe Lyon wrote:

> On aarch64*-elf and arm-eabi (using newlib), I'm seeing:
> /gccsrc/libstdc++-v3/libsupc++/new_opa.cc:66: undefined reference to
> `aligned_alloc'

https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;a=commit;h=f86afe5a3ac62a92e821c764a011e1625abdd326

"C11 aligned_alloc() implementation

aligned_alloc() is implemented in terms of posix_memalign() which is
only declared in <stdlib.h> but not defined in Newlib in general.  At
least Linux and RTEMS implement this function."

If we don't want to provide a fallback implementation in libsupc++, we can 
say that aligned new is unsupported on those platforms, but if we are 
building a shared libstdc++.so that doesn't like undefined symbols, we 
need a different failure mode than an undefined aligned_alloc. Either not 
providing operator new(...aligned_val_t...) in libstdc++ or providing one 
that just aborts I guess?

-- 
Marc Glisse

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: RFA (libstdc++): PATCH to implement C++17 over-aligned new
  2016-09-10 10:14         ` Marc Glisse
@ 2016-09-10 10:35           ` Jonathan Wakely
  0 siblings, 0 replies; 42+ messages in thread
From: Jonathan Wakely @ 2016-09-10 10:35 UTC (permalink / raw)
  To: libstdc++; +Cc: Christophe Lyon, Jason Merrill, gcc-patches List

On 10/09/16 11:25 +0200, Marc Glisse wrote:
>On Sat, 10 Sep 2016, Christophe Lyon wrote:
>
>>On aarch64*-elf and arm-eabi (using newlib), I'm seeing:
>>/gccsrc/libstdc++-v3/libsupc++/new_opa.cc:66: undefined reference to
>>`aligned_alloc'
>
>https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;a=commit;h=f86afe5a3ac62a92e821c764a011e1625abdd326
>
>"C11 aligned_alloc() implementation
>
>aligned_alloc() is implemented in terms of posix_memalign() which is
>only declared in <stdlib.h> but not defined in Newlib in general.  At
>least Linux and RTEMS implement this function."
>
>If we don't want to provide a fallback implementation in libsupc++, we 
>can say that aligned new is unsupported on those platforms, but if we 
>are building a shared libstdc++.so that doesn't like undefined 
>symbols, we need a different failure mode than an undefined 
>aligned_alloc. Either not providing operator new(...aligned_val_t...) 
>in libstdc++ or providing one that just aborts I guess?

Or always fails with bad_alloc:

--- a/libstdc++-v3/libsupc++/new_opa.cc
+++ b/libstdc++-v3/libsupc++/new_opa.cc
@@ -49,8 +49,11 @@ aligned_alloc (std::size_t al, std::size_t sz)
 #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);
+// an aligned_alloc that always fails.
+static void *aligned_alloc(std::size_t, std::size_t)
+{
+  _GLIBCXX_THROW_OR_ABORT(bad_alloc());
+}
 #endif
 #endif
 
That would work unless/until we get a fallback.

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: RFA (libstdc++): PATCH to implement C++17 over-aligned new
  2016-09-09 21:40     ` Jason Merrill
  2016-09-10  7:03       ` Christophe Lyon
  2016-09-10 10:14       ` Jonathan Wakely
@ 2016-09-11  7:09       ` Andreas Schwab
  2016-09-12 21:13         ` Jason Merrill
  2016-09-12 14:15       ` Rainer Orth
  3 siblings, 1 reply; 42+ messages in thread
From: Andreas Schwab @ 2016-09-11  7:09 UTC (permalink / raw)
  To: Jason Merrill; +Cc: Jonathan Wakely, libstdc++, gcc-patches List

FAIL: g++.dg/cpp1z/aligned-new1.C   (test for excess errors)
Excess errors:
/daten/aranym/gcc/gcc-20160910/gcc/testsuite/g++.dg/cpp1z/aligned-new1.C:10:20: warning: requested alignment 64 is larger than 16 [-Wattributes]
FAIL: g++.dg/cpp1z/aligned-new1.C   execution test
FAIL: g++.dg/cpp1z/aligned-new4.C    (test for warnings, line 11)
FAIL: g++.dg/cpp1z/aligned-new4.C   (test for excess errors)
Excess errors:
/daten/aranym/gcc/gcc-20160910/gcc/testsuite/g++.dg/cpp1z/aligned-new4.C:3:20: warning: requested alignment 64 is larger than 16 [-Wattributes]
/daten/aranym/gcc/gcc-20160910/gcc/testsuite/g++.dg/cpp1z/aligned-new4.C:4:20: warning: requested alignment 64 is larger than 16 [-Wattributes]
FAIL: g++.dg/cpp1z/aligned-new5.C  -std=gnu++11 (test for excess errors)
Excess errors:
aligned-new5.C:(.text+0xe): undefined reference to `operator new(unsigned int, std::align_val_t)'

Andreas.

-- 
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: RFA (libstdc++): PATCH to implement C++17 over-aligned new
  2016-09-10  7:03       ` Christophe Lyon
  2016-09-10 10:14         ` Marc Glisse
@ 2016-09-11  9:14         ` Christophe Lyon
  2016-09-11  9:55           ` Jonathan Wakely
  2016-09-13 13:04         ` Szabolcs Nagy
  2 siblings, 1 reply; 42+ messages in thread
From: Christophe Lyon @ 2016-09-11  9:14 UTC (permalink / raw)
  To: Jason Merrill; +Cc: Jonathan Wakely, libstdc++, gcc-patches List

On 10 September 2016 at 08:59, Christophe Lyon
<christophe.lyon@linaro.org> wrote:
> On 9 September 2016 at 23:20, Jason Merrill <jason@redhat.com> wrote:
>> On Thu, Sep 8, 2016 at 7:06 AM, Jonathan Wakely <jwakely@redhat.com> wrote:
>>> On 08/09/16 09:10 +0200, Marc Glisse wrote:
>>>>
>>>> Do we want a generic fallback implementation (similar to
>>>> gcc/config/i386/gmm_malloc.h)? A windows version with _aligned_malloc /
>>>> _aligned_free would also be possible.
>>>
>>> Making it work for MinGW would be nice.
>>
>> OK, this is what I'm checking in; could someone test it on MinGW?
>>
>> Jason
>
> Hi Jason,
>
> I'm seeing problems on arm*linux: the tests aligned-new[1235].C fail to link:
> aligned-new5.C:(.text+0x14): undefined reference to `operator
> new(unsigned int, std::align_val_t)'
>
>
> On aarch64*-elf and arm-eabi (using newlib), I'm seeing:
> /gccsrc/libstdc++-v3/libsupc++/new_opa.cc:66: undefined reference to
> `aligned_alloc'
>
> Am I missing something in my setup?
>

I'm seeing an additional problem: to GCC build is broken after this
commit for target arm-none-eabi (using default cpu):
/home/christophe.lyon/src/GCC/sources/gcc-fsf/reg-240062/libstdc++-v3/libsupc++/new_opant.cc:
In function 'void* operator new(std::size_t, std::align_val_t, const
std::nothrow_t&)':
/home/christophe.lyon/src/GCC/sources/gcc-fsf/reg-240062/libstdc++-v3/libsupc++/new_opant.cc:33:3:
error: '__try' was not declared in this scope
   __try
   ^~~~~
/home/christophe.lyon/src/GCC/sources/gcc-fsf/reg-240062/libstdc++-v3/libsupc++/new_opant.cc:37:11:
error: expected primary-expression before '...' token
   __catch(...)
           ^~~
/home/christophe.lyon/src/GCC/sources/gcc-fsf/reg-240062/libstdc++-v3/libsupc++/new_opant.cc:37:3:
error: '__catch' was not declared in this scope
   __catch(...)
   ^~~~~~~
/home/christophe.lyon/src/GCC/sources/gcc-fsf/reg-240062/libstdc++-v3/libsupc++/new_opant.cc:41:1:
warning: no return statement in function returning non-void
[-Wreturn-type]
 }
 ^
/home/christophe.lyon/src/GCC/sources/gcc-fsf/reg-240062/libstdc++-v3/libsupc++/new_opant.cc:30:26:
warning: unused parameter 'sz' [-Wunused-parameter]
 operator new(std::size_t sz, std::align_val_t al, const std::nothrow_t&)
                          ^~
/home/christophe.lyon/src/GCC/sources/gcc-fsf/reg-240062/libstdc++-v3/libsupc++/new_opant.cc:30:47:
warning: unused parameter 'al' [-Wunused-parameter]
 operator new(std::size_t sz, std::align_val_t al, const std::nothrow_t&)
                                               ^~
make[4]: *** [new_opant.lo] Error 1
make[4]: Leaving directory
`/home/christophe.lyon/src/GCC/builds/gcc-fsf-reg-240062/obj-arm-none-eabi/gcc3/arm-none-eabi/libstdc++-v3/libsupc++'

Let me know if you need more details.

Thanks,

Christophe


> Thanks,
>
> Christophe

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: RFA (libstdc++): PATCH to implement C++17 over-aligned new
  2016-09-11  9:14         ` Christophe Lyon
@ 2016-09-11  9:55           ` Jonathan Wakely
  2016-09-11  9:56             ` Jonathan Wakely
  2016-09-11 10:20             ` Christophe Lyon
  0 siblings, 2 replies; 42+ messages in thread
From: Jonathan Wakely @ 2016-09-11  9:55 UTC (permalink / raw)
  To: Christophe Lyon; +Cc: Jason Merrill, libstdc++, gcc-patches List

[-- Attachment #1: Type: text/plain, Size: 2924 bytes --]

On 11/09/16 09:08 +0200, Christophe Lyon wrote:
>On 10 September 2016 at 08:59, Christophe Lyon
><christophe.lyon@linaro.org> wrote:
>> On 9 September 2016 at 23:20, Jason Merrill <jason@redhat.com> wrote:
>>> On Thu, Sep 8, 2016 at 7:06 AM, Jonathan Wakely <jwakely@redhat.com> wrote:
>>>> On 08/09/16 09:10 +0200, Marc Glisse wrote:
>>>>>
>>>>> Do we want a generic fallback implementation (similar to
>>>>> gcc/config/i386/gmm_malloc.h)? A windows version with _aligned_malloc /
>>>>> _aligned_free would also be possible.
>>>>
>>>> Making it work for MinGW would be nice.
>>>
>>> OK, this is what I'm checking in; could someone test it on MinGW?
>>>
>>> Jason
>>
>> Hi Jason,
>>
>> I'm seeing problems on arm*linux: the tests aligned-new[1235].C fail to link:
>> aligned-new5.C:(.text+0x14): undefined reference to `operator
>> new(unsigned int, std::align_val_t)'
>>
>>
>> On aarch64*-elf and arm-eabi (using newlib), I'm seeing:
>> /gccsrc/libstdc++-v3/libsupc++/new_opa.cc:66: undefined reference to
>> `aligned_alloc'
>>
>> Am I missing something in my setup?
>>
>
>I'm seeing an additional problem: to GCC build is broken after this
>commit for target arm-none-eabi (using default cpu):
>/home/christophe.lyon/src/GCC/sources/gcc-fsf/reg-240062/libstdc++-v3/libsupc++/new_opant.cc:
>In function 'void* operator new(std::size_t, std::align_val_t, const
>std::nothrow_t&)':
>/home/christophe.lyon/src/GCC/sources/gcc-fsf/reg-240062/libstdc++-v3/libsupc++/new_opant.cc:33:3:
>error: '__try' was not declared in this scope
>   __try
>   ^~~~~
>/home/christophe.lyon/src/GCC/sources/gcc-fsf/reg-240062/libstdc++-v3/libsupc++/new_opant.cc:37:11:
>error: expected primary-expression before '...' token
>   __catch(...)
>           ^~~
>/home/christophe.lyon/src/GCC/sources/gcc-fsf/reg-240062/libstdc++-v3/libsupc++/new_opant.cc:37:3:
>error: '__catch' was not declared in this scope
>   __catch(...)
>   ^~~~~~~
>/home/christophe.lyon/src/GCC/sources/gcc-fsf/reg-240062/libstdc++-v3/libsupc++/new_opant.cc:41:1:
>warning: no return statement in function returning non-void
>[-Wreturn-type]
> }
> ^
>/home/christophe.lyon/src/GCC/sources/gcc-fsf/reg-240062/libstdc++-v3/libsupc++/new_opant.cc:30:26:
>warning: unused parameter 'sz' [-Wunused-parameter]
> operator new(std::size_t sz, std::align_val_t al, const std::nothrow_t&)
>                          ^~
>/home/christophe.lyon/src/GCC/sources/gcc-fsf/reg-240062/libstdc++-v3/libsupc++/new_opant.cc:30:47:
>warning: unused parameter 'al' [-Wunused-parameter]
> operator new(std::size_t sz, std::align_val_t al, const std::nothrow_t&)
>                                               ^~
>make[4]: *** [new_opant.lo] Error 1
>make[4]: Leaving directory
>`/home/christophe.lyon/src/GCC/builds/gcc-fsf-reg-240062/obj-arm-none-eabi/gcc3/arm-none-eabi/libstdc++-v3/libsupc++'

Hmm, I'm not sure why it's not failing on all targets, but this should
fix it. Could you test it?


[-- Attachment #2: patch.txt --]
[-- Type: text/x-patch, Size: 256 bytes --]

--- a/libstdc++-v3/libsupc++/new_opant.cc
+++ b/libstdc++-v3/libsupc++/new_opant.cc
@@ -24,6 +24,7 @@
 // <http://www.gnu.org/licenses/>.
 
 #include <bits/c++config.h>
+#include <bits/exception_defines.h>
 #include "new"
 
 _GLIBCXX_WEAK_DEFINITION void*

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: RFA (libstdc++): PATCH to implement C++17 over-aligned new
  2016-09-11  9:55           ` Jonathan Wakely
@ 2016-09-11  9:56             ` Jonathan Wakely
  2016-09-11 10:20             ` Christophe Lyon
  1 sibling, 0 replies; 42+ messages in thread
From: Jonathan Wakely @ 2016-09-11  9:56 UTC (permalink / raw)
  To: Christophe Lyon; +Cc: Jason Merrill, libstdc++, gcc-patches List

On 11/09/16 10:38 +0100, Jonathan Wakely wrote:
>On 11/09/16 09:08 +0200, Christophe Lyon wrote:
>>On 10 September 2016 at 08:59, Christophe Lyon
>><christophe.lyon@linaro.org> wrote:
>>>On 9 September 2016 at 23:20, Jason Merrill <jason@redhat.com> wrote:
>>>>On Thu, Sep 8, 2016 at 7:06 AM, Jonathan Wakely <jwakely@redhat.com> wrote:
>>>>>On 08/09/16 09:10 +0200, Marc Glisse wrote:
>>>>>>
>>>>>>Do we want a generic fallback implementation (similar to
>>>>>>gcc/config/i386/gmm_malloc.h)? A windows version with _aligned_malloc /
>>>>>>_aligned_free would also be possible.
>>>>>
>>>>>Making it work for MinGW would be nice.
>>>>
>>>>OK, this is what I'm checking in; could someone test it on MinGW?
>>>>
>>>>Jason
>>>
>>>Hi Jason,
>>>
>>>I'm seeing problems on arm*linux: the tests aligned-new[1235].C fail to link:
>>>aligned-new5.C:(.text+0x14): undefined reference to `operator
>>>new(unsigned int, std::align_val_t)'
>>>
>>>
>>>On aarch64*-elf and arm-eabi (using newlib), I'm seeing:
>>>/gccsrc/libstdc++-v3/libsupc++/new_opa.cc:66: undefined reference to
>>>`aligned_alloc'
>>>
>>>Am I missing something in my setup?
>>>
>>
>>I'm seeing an additional problem: to GCC build is broken after this
>>commit for target arm-none-eabi (using default cpu):
>>/home/christophe.lyon/src/GCC/sources/gcc-fsf/reg-240062/libstdc++-v3/libsupc++/new_opant.cc:
>>In function 'void* operator new(std::size_t, std::align_val_t, const
>>std::nothrow_t&)':
>>/home/christophe.lyon/src/GCC/sources/gcc-fsf/reg-240062/libstdc++-v3/libsupc++/new_opant.cc:33:3:
>>error: '__try' was not declared in this scope
>>  __try
>>  ^~~~~
>>/home/christophe.lyon/src/GCC/sources/gcc-fsf/reg-240062/libstdc++-v3/libsupc++/new_opant.cc:37:11:
>>error: expected primary-expression before '...' token
>>  __catch(...)
>>          ^~~
>>/home/christophe.lyon/src/GCC/sources/gcc-fsf/reg-240062/libstdc++-v3/libsupc++/new_opant.cc:37:3:
>>error: '__catch' was not declared in this scope
>>  __catch(...)
>>  ^~~~~~~
>>/home/christophe.lyon/src/GCC/sources/gcc-fsf/reg-240062/libstdc++-v3/libsupc++/new_opant.cc:41:1:
>>warning: no return statement in function returning non-void
>>[-Wreturn-type]
>>}
>>^
>>/home/christophe.lyon/src/GCC/sources/gcc-fsf/reg-240062/libstdc++-v3/libsupc++/new_opant.cc:30:26:
>>warning: unused parameter 'sz' [-Wunused-parameter]
>>operator new(std::size_t sz, std::align_val_t al, const std::nothrow_t&)
>>                         ^~
>>/home/christophe.lyon/src/GCC/sources/gcc-fsf/reg-240062/libstdc++-v3/libsupc++/new_opant.cc:30:47:
>>warning: unused parameter 'al' [-Wunused-parameter]
>>operator new(std::size_t sz, std::align_val_t al, const std::nothrow_t&)
>>                                              ^~
>>make[4]: *** [new_opant.lo] Error 1
>>make[4]: Leaving directory
>>`/home/christophe.lyon/src/GCC/builds/gcc-fsf-reg-240062/obj-arm-none-eabi/gcc3/arm-none-eabi/libstdc++-v3/libsupc++'
>
>Hmm, I'm not sure why it's not failing on all targets, [...]

OK, I see why. <bits/exception_defines.h> gets included indirectly at
the end of <exception> via

#if (__cplusplus >= 201103L) && (ATOMIC_INT_LOCK_FREE > 1)
#include <bits/exception_ptr.h>
#include <bits/nested_exception.h>
#endif

The condition isn't true for all targets.

So including it explicitly in new_opant.cc is the right fix.

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: RFA (libstdc++): PATCH to implement C++17 over-aligned new
  2016-09-11  9:55           ` Jonathan Wakely
  2016-09-11  9:56             ` Jonathan Wakely
@ 2016-09-11 10:20             ` Christophe Lyon
  2016-09-11 12:09               ` Jonathan Wakely
  1 sibling, 1 reply; 42+ messages in thread
From: Christophe Lyon @ 2016-09-11 10:20 UTC (permalink / raw)
  To: Jonathan Wakely; +Cc: Jason Merrill, libstdc++, gcc-patches List

On 11 September 2016 at 11:38, Jonathan Wakely <jwakely@redhat.com> wrote:
> On 11/09/16 09:08 +0200, Christophe Lyon wrote:
>>
>> On 10 September 2016 at 08:59, Christophe Lyon
>> <christophe.lyon@linaro.org> wrote:
>>>
>>> On 9 September 2016 at 23:20, Jason Merrill <jason@redhat.com> wrote:
>>>>
>>>> On Thu, Sep 8, 2016 at 7:06 AM, Jonathan Wakely <jwakely@redhat.com>
>>>> wrote:
>>>>>
>>>>> On 08/09/16 09:10 +0200, Marc Glisse wrote:
>>>>>>
>>>>>>
>>>>>> Do we want a generic fallback implementation (similar to
>>>>>> gcc/config/i386/gmm_malloc.h)? A windows version with _aligned_malloc
>>>>>> /
>>>>>> _aligned_free would also be possible.
>>>>>
>>>>>
>>>>> Making it work for MinGW would be nice.
>>>>
>>>>
>>>> OK, this is what I'm checking in; could someone test it on MinGW?
>>>>
>>>> Jason
>>>
>>>
>>> Hi Jason,
>>>
>>> I'm seeing problems on arm*linux: the tests aligned-new[1235].C fail to
>>> link:
>>> aligned-new5.C:(.text+0x14): undefined reference to `operator
>>> new(unsigned int, std::align_val_t)'
>>>
>>>
>>> On aarch64*-elf and arm-eabi (using newlib), I'm seeing:
>>> /gccsrc/libstdc++-v3/libsupc++/new_opa.cc:66: undefined reference to
>>> `aligned_alloc'
>>>
>>> Am I missing something in my setup?
>>>
>>
>> I'm seeing an additional problem: to GCC build is broken after this
>> commit for target arm-none-eabi (using default cpu):
>>
>> /home/christophe.lyon/src/GCC/sources/gcc-fsf/reg-240062/libstdc++-v3/libsupc++/new_opant.cc:
>> In function 'void* operator new(std::size_t, std::align_val_t, const
>> std::nothrow_t&)':
>>
>> /home/christophe.lyon/src/GCC/sources/gcc-fsf/reg-240062/libstdc++-v3/libsupc++/new_opant.cc:33:3:
>> error: '__try' was not declared in this scope
>>   __try
>>   ^~~~~
>>
>> /home/christophe.lyon/src/GCC/sources/gcc-fsf/reg-240062/libstdc++-v3/libsupc++/new_opant.cc:37:11:
>> error: expected primary-expression before '...' token
>>   __catch(...)
>>           ^~~
>>
>> /home/christophe.lyon/src/GCC/sources/gcc-fsf/reg-240062/libstdc++-v3/libsupc++/new_opant.cc:37:3:
>> error: '__catch' was not declared in this scope
>>   __catch(...)
>>   ^~~~~~~
>>
>> /home/christophe.lyon/src/GCC/sources/gcc-fsf/reg-240062/libstdc++-v3/libsupc++/new_opant.cc:41:1:
>> warning: no return statement in function returning non-void
>> [-Wreturn-type]
>> }
>> ^
>>
>> /home/christophe.lyon/src/GCC/sources/gcc-fsf/reg-240062/libstdc++-v3/libsupc++/new_opant.cc:30:26:
>> warning: unused parameter 'sz' [-Wunused-parameter]
>> operator new(std::size_t sz, std::align_val_t al, const std::nothrow_t&)
>>                          ^~
>>
>> /home/christophe.lyon/src/GCC/sources/gcc-fsf/reg-240062/libstdc++-v3/libsupc++/new_opant.cc:30:47:
>> warning: unused parameter 'al' [-Wunused-parameter]
>> operator new(std::size_t sz, std::align_val_t al, const std::nothrow_t&)
>>                                               ^~
>> make[4]: *** [new_opant.lo] Error 1
>> make[4]: Leaving directory
>>
>> `/home/christophe.lyon/src/GCC/builds/gcc-fsf-reg-240062/obj-arm-none-eabi/gcc3/arm-none-eabi/libstdc++-v3/libsupc++'
>
>
> Hmm, I'm not sure why it's not failing on all targets, but this should
I don't know either: the same target (arm-none-eabi) but
--with-cpu=cortex-a9 does build.

> fix it. Could you test it?
>
It's not sufficient: I had to apply the same change to new_opvant.cc
for the build to complete.

Thanks,

Christophe

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: RFA (libstdc++): PATCH to implement C++17 over-aligned new
  2016-09-11 10:20             ` Christophe Lyon
@ 2016-09-11 12:09               ` Jonathan Wakely
  0 siblings, 0 replies; 42+ messages in thread
From: Jonathan Wakely @ 2016-09-11 12:09 UTC (permalink / raw)
  To: Christophe Lyon; +Cc: Jason Merrill, libstdc++, gcc-patches List

[-- Attachment #1: Type: text/plain, Size: 505 bytes --]

On 11/09/16 11:55 +0200, Christophe Lyon wrote:
>On 11 September 2016 at 11:38, Jonathan Wakely <jwakely@redhat.com> wrote:
>> Hmm, I'm not sure why it's not failing on all targets, but this should
>I don't know either: the same target (arm-none-eabi) but
>--with-cpu=cortex-a9 does build.
>
>> fix it. Could you test it?
>>
>It's not sufficient: I had to apply the same change to new_opvant.cc
>for the build to complete.

Tested powerpc64le-linux.  Committed to trunk.

Thanks for the quick testing.




[-- Attachment #2: patch.txt --]
[-- Type: text/x-patch, Size: 1047 bytes --]

commit 8f127734ff660dabfe6c8f196e34ccc5dc436518
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Sun Sep 11 11:07:22 2016 +0100

    Fix bootstrap failure when ATOMIC_INT_LOCK_FREE < 2
    
    	* libsupc++/new_opant.cc: Include exception_defines.h.
    	* libsupc++/new_opvant.cc: Likewise.

diff --git a/libstdc++-v3/libsupc++/new_opant.cc b/libstdc++-v3/libsupc++/new_opant.cc
index c863d64..1c6ccab 100644
--- a/libstdc++-v3/libsupc++/new_opant.cc
+++ b/libstdc++-v3/libsupc++/new_opant.cc
@@ -24,6 +24,7 @@
 // <http://www.gnu.org/licenses/>.
 
 #include <bits/c++config.h>
+#include <bits/exception_defines.h>
 #include "new"
 
 _GLIBCXX_WEAK_DEFINITION void*
diff --git a/libstdc++-v3/libsupc++/new_opvant.cc b/libstdc++-v3/libsupc++/new_opvant.cc
index a32fec8..2b29547 100644
--- a/libstdc++-v3/libsupc++/new_opvant.cc
+++ b/libstdc++-v3/libsupc++/new_opvant.cc
@@ -24,6 +24,7 @@
 // <http://www.gnu.org/licenses/>.
 
 #include <bits/c++config.h>
+#include <bits/exception_defines.h>
 #include "new"
 
 _GLIBCXX_WEAK_DEFINITION void*

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: RFA (libstdc++): PATCH to implement C++17 over-aligned new
  2016-09-09 21:40     ` Jason Merrill
                         ` (2 preceding siblings ...)
  2016-09-11  7:09       ` Andreas Schwab
@ 2016-09-12 14:15       ` Rainer Orth
  2016-09-12 16:19         ` Jonathan Wakely
  3 siblings, 1 reply; 42+ messages in thread
From: Rainer Orth @ 2016-09-12 14:15 UTC (permalink / raw)
  To: Jason Merrill; +Cc: Jonathan Wakely, libstdc++, gcc-patches List

Jason Merrill <jason@redhat.com> writes:

> On Thu, Sep 8, 2016 at 7:06 AM, Jonathan Wakely <jwakely@redhat.com> wrote:
>> On 08/09/16 09:10 +0200, Marc Glisse wrote:
>>>
>>> Do we want a generic fallback implementation (similar to
>>> gcc/config/i386/gmm_malloc.h)? A windows version with _aligned_malloc /
>>> _aligned_free would also be possible.
>>
>> Making it work for MinGW would be nice.
>
> OK, this is what I'm checking in; could someone test it on MinGW?

The new tests are failing in various ways on Solaris:

* 32-bit:

+FAIL: g++.dg/cpp1z/aligned-new1.C   (test for excess errors)
+WARNING: g++.dg/cpp1z/aligned-new1.C   compilation failed to produce executable
+FAIL: g++.dg/cpp1z/aligned-new2.C   (test for excess errors)
+WARNING: g++.dg/cpp1z/aligned-new2.C   compilation failed to produce executable
+FAIL: g++.dg/cpp1z/aligned-new3.C   (test for excess errors)
+WARNING: g++.dg/cpp1z/aligned-new3.C   compilation failed to produce executable
+FAIL: g++.dg/cpp1z/aligned-new5.C  -std=gnu++11 (test for excess errors)
+WARNING: g++.dg/cpp1z/aligned-new5.C  -std=gnu++11 compilation failed to produc
e executable
+FAIL: g++.dg/cpp1z/aligned-new5.C  -std=gnu++14 (test for excess errors)
+WARNING: g++.dg/cpp1z/aligned-new5.C  -std=gnu++14 compilation failed to produc
e executable
+FAIL: g++.dg/cpp1z/aligned-new5.C  -std=gnu++98 (test for excess errors)
+WARNING: g++.dg/cpp1z/aligned-new5.C  -std=gnu++98 compilation failed to produc
e executable

  All instances of

Excess errors:
Undefined                       first referenced
 symbol                             in file
operator new(unsigned int, std::align_val_t) /var/tmp//cc_0Nrkd.o
ld: fatal: symbol referencing errors

  libsupc++/new_opa.o contains

  _ZnwjSt11align_val_t (operator new(unsigned int, std::align_val_t))

  while for 64-bit there is

  _ZnwmSt11align_val_t (operator new(unsigned long, std::align_val_t))

  The former isn't matched by config/abi/pre/gnu.ver

    # C++17 aligned new/delete
    _ZnwmSt11align_val_t;
    _ZnwmSt11align_val_tRKSt9nothrow_t;
    _ZnamSt11align_val_t;
    _ZnamSt11align_val_tRKSt9nothrow_t;

  I strongly suspects this needs to be

  _Znw[jmy]* just as for regular new/delete.

* For 64-bit, I get

+FAIL: g++.dg/cpp1z/aligned-new5.C  -std=gnu++11 execution test
+FAIL: g++.dg/cpp1z/aligned-new5.C  -std=gnu++14 execution test
+FAIL: g++.dg/cpp1z/aligned-new5.C  -std=gnu++98 execution test

  which fails like this:

terminate called after throwing an instance of 'std::bad_alloc'
  what():  std::bad_alloc

  gdb shows

#7  0xffff80ff1d104bdc in __cxxabiv1::__cxa_throw (obj=<optimized out>, 
    tinfo=0xffff80ff1d2d0c98 <typeinfo for std::bad_alloc>, 
    dest=0xffff80ff1d1028f0 <std::bad_alloc::~bad_alloc()>)
    at /vol/gcc/src/hg/trunk/local/libstdc++-v3/libsupc++/eh_throw.cc:96
#8  0xffff80ff1d10604c in operator new (sz=4, al=(unknown: 64))
    at /vol/gcc/src/hg/trunk/local/libstdc++-v3/libsupc++/new_opa.cc:71
#9  0x00000000004010df in main ()
    at /vol/gcc/src/hg/trunk/local/gcc/testsuite/g++.dg/cpp1z/aligned-new5.C:11

  and aligned_alloc(3C) documents

       The  value of alignment must be a valid alignment supported by the sys-
       tem, that is, any power of two (1, 2, 4, 8, ...), and the value of size
       must be an integral multiple of alignment.

  which isn't the case here.

  Rainer

-- 
-----------------------------------------------------------------------------
Rainer Orth, Center for Biotechnology, Bielefeld University

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: RFA (libstdc++): PATCH to implement C++17 over-aligned new
  2016-09-12 14:15       ` Rainer Orth
@ 2016-09-12 16:19         ` Jonathan Wakely
  2016-09-12 18:57           ` Jason Merrill
  2016-09-14 12:11           ` Rainer Orth
  0 siblings, 2 replies; 42+ messages in thread
From: Jonathan Wakely @ 2016-09-12 16:19 UTC (permalink / raw)
  To: Rainer Orth; +Cc: Jason Merrill, libstdc++, gcc-patches List

[-- Attachment #1: Type: text/plain, Size: 3717 bytes --]

On 12/09/16 16:13 +0200, Rainer Orth wrote:
>Jason Merrill <jason@redhat.com> writes:
>
>> On Thu, Sep 8, 2016 at 7:06 AM, Jonathan Wakely <jwakely@redhat.com> wrote:
>>> On 08/09/16 09:10 +0200, Marc Glisse wrote:
>>>>
>>>> Do we want a generic fallback implementation (similar to
>>>> gcc/config/i386/gmm_malloc.h)? A windows version with _aligned_malloc /
>>>> _aligned_free would also be possible.
>>>
>>> Making it work for MinGW would be nice.
>>
>> OK, this is what I'm checking in; could someone test it on MinGW?
>
>The new tests are failing in various ways on Solaris:
>
>* 32-bit:
>
>+FAIL: g++.dg/cpp1z/aligned-new1.C   (test for excess errors)
>+WARNING: g++.dg/cpp1z/aligned-new1.C   compilation failed to produce executable
>+FAIL: g++.dg/cpp1z/aligned-new2.C   (test for excess errors)
>+WARNING: g++.dg/cpp1z/aligned-new2.C   compilation failed to produce executable
>+FAIL: g++.dg/cpp1z/aligned-new3.C   (test for excess errors)
>+WARNING: g++.dg/cpp1z/aligned-new3.C   compilation failed to produce executable
>+FAIL: g++.dg/cpp1z/aligned-new5.C  -std=gnu++11 (test for excess errors)
>+WARNING: g++.dg/cpp1z/aligned-new5.C  -std=gnu++11 compilation failed to produc
>e executable
>+FAIL: g++.dg/cpp1z/aligned-new5.C  -std=gnu++14 (test for excess errors)
>+WARNING: g++.dg/cpp1z/aligned-new5.C  -std=gnu++14 compilation failed to produc
>e executable
>+FAIL: g++.dg/cpp1z/aligned-new5.C  -std=gnu++98 (test for excess errors)
>+WARNING: g++.dg/cpp1z/aligned-new5.C  -std=gnu++98 compilation failed to produc
>e executable
>
>  All instances of
>
>Excess errors:
>Undefined                       first referenced
> symbol                             in file
>operator new(unsigned int, std::align_val_t) /var/tmp//cc_0Nrkd.o
>ld: fatal: symbol referencing errors
>
>  libsupc++/new_opa.o contains
>
>  _ZnwjSt11align_val_t (operator new(unsigned int, std::align_val_t))
>
>  while for 64-bit there is
>
>  _ZnwmSt11align_val_t (operator new(unsigned long, std::align_val_t))
>
>  The former isn't matched by config/abi/pre/gnu.ver
>
>    # C++17 aligned new/delete
>    _ZnwmSt11align_val_t;
>    _ZnwmSt11align_val_tRKSt9nothrow_t;
>    _ZnamSt11align_val_t;
>    _ZnamSt11align_val_tRKSt9nothrow_t;
>
>  I strongly suspects this needs to be
>
>  _Znw[jmy]* just as for regular new/delete.

Yes, that's right. Patch approved if you want to change that (I won't
be able to until tomorrow).

>* For 64-bit, I get
>
>+FAIL: g++.dg/cpp1z/aligned-new5.C  -std=gnu++11 execution test
>+FAIL: g++.dg/cpp1z/aligned-new5.C  -std=gnu++14 execution test
>+FAIL: g++.dg/cpp1z/aligned-new5.C  -std=gnu++98 execution test
>
>  which fails like this:
>
>terminate called after throwing an instance of 'std::bad_alloc'
>  what():  std::bad_alloc
>
>  gdb shows
>
>#7  0xffff80ff1d104bdc in __cxxabiv1::__cxa_throw (obj=<optimized out>,
>    tinfo=0xffff80ff1d2d0c98 <typeinfo for std::bad_alloc>,
>    dest=0xffff80ff1d1028f0 <std::bad_alloc::~bad_alloc()>)
>    at /vol/gcc/src/hg/trunk/local/libstdc++-v3/libsupc++/eh_throw.cc:96
>#8  0xffff80ff1d10604c in operator new (sz=4, al=(unknown: 64))
>    at /vol/gcc/src/hg/trunk/local/libstdc++-v3/libsupc++/new_opa.cc:71
>#9  0x00000000004010df in main ()
>    at /vol/gcc/src/hg/trunk/local/gcc/testsuite/g++.dg/cpp1z/aligned-new5.C:11
>
>  and aligned_alloc(3C) documents
>
>       The  value of alignment must be a valid alignment supported by the sys-
>       tem, that is, any power of two (1, 2, 4, 8, ...), and the value of size
>       must be an integral multiple of alignment.
>
>  which isn't the case here.

Ah, it seems GNU's aligned_alloc doesn't check that requirement. So we
need to increase the requested size, maybe something like this patch.




[-- Attachment #2: patch.txt --]
[-- Type: text/x-patch, Size: 730 bytes --]

diff --git a/libstdc++-v3/libsupc++/new_opa.cc b/libstdc++-v3/libsupc++/new_opa.cc
index 6ff5421..f2c0fdb 100644
--- a/libstdc++-v3/libsupc++/new_opa.cc
+++ b/libstdc++-v3/libsupc++/new_opa.cc
@@ -58,12 +58,15 @@ _GLIBCXX_WEAK_DEFINITION void *
 operator new (std::size_t sz, std::align_val_t al)
 {
   void *p;
+  std::size_t align = (std::size_t)al;
 
   /* malloc (0) is unpredictable; avoid it.  */
   if (sz == 0)
-    sz = 1;
+    sz = align;
+  if (std::size_t rem = sz % align)
+    sz += align - rem;
 
-  while (__builtin_expect ((p = aligned_alloc ((std::size_t)al, sz)) == 0,
+  while (__builtin_expect ((p = aligned_alloc (align, sz)) == 0,
 			   false))
     {
       new_handler handler = std::get_new_handler ();

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: RFA (libstdc++): PATCH to implement C++17 over-aligned new
  2016-09-12 16:19         ` Jonathan Wakely
@ 2016-09-12 18:57           ` Jason Merrill
  2016-09-14 12:11           ` Rainer Orth
  1 sibling, 0 replies; 42+ messages in thread
From: Jason Merrill @ 2016-09-12 18:57 UTC (permalink / raw)
  To: Jonathan Wakely; +Cc: Rainer Orth, libstdc++, gcc-patches List

[-- Attachment #1: Type: text/plain, Size: 2634 bytes --]

On Mon, Sep 12, 2016 at 12:10 PM, Jonathan Wakely <jwakely@redhat.com> wrote:
> On 12/09/16 16:13 +0200, Rainer Orth wrote:
>>
>> Jason Merrill <jason@redhat.com> writes:
>>
>>> On Thu, Sep 8, 2016 at 7:06 AM, Jonathan Wakely <jwakely@redhat.com>
>>> wrote:
>>>>
>>>> On 08/09/16 09:10 +0200, Marc Glisse wrote:
>>>>>
>>>>>
>>>>> Do we want a generic fallback implementation (similar to
>>>>> gcc/config/i386/gmm_malloc.h)? A windows version with _aligned_malloc /
>>>>> _aligned_free would also be possible.
>>>>
>>>>
>>>> Making it work for MinGW would be nice.
>>>
>>>
>>> OK, this is what I'm checking in; could someone test it on MinGW?
>>
>>
>> The new tests are failing in various ways on Solaris:
>>
>> * 32-bit:
>>
>> +FAIL: g++.dg/cpp1z/aligned-new1.C   (test for excess errors)
>> +WARNING: g++.dg/cpp1z/aligned-new1.C   compilation failed to produce
>> executable
>> +FAIL: g++.dg/cpp1z/aligned-new2.C   (test for excess errors)
>> +WARNING: g++.dg/cpp1z/aligned-new2.C   compilation failed to produce
>> executable
>> +FAIL: g++.dg/cpp1z/aligned-new3.C   (test for excess errors)
>> +WARNING: g++.dg/cpp1z/aligned-new3.C   compilation failed to produce
>> executable
>> +FAIL: g++.dg/cpp1z/aligned-new5.C  -std=gnu++11 (test for excess errors)
>> +WARNING: g++.dg/cpp1z/aligned-new5.C  -std=gnu++11 compilation failed to
>> produc
>> e executable
>> +FAIL: g++.dg/cpp1z/aligned-new5.C  -std=gnu++14 (test for excess errors)
>> +WARNING: g++.dg/cpp1z/aligned-new5.C  -std=gnu++14 compilation failed to
>> produc
>> e executable
>> +FAIL: g++.dg/cpp1z/aligned-new5.C  -std=gnu++98 (test for excess errors)
>> +WARNING: g++.dg/cpp1z/aligned-new5.C  -std=gnu++98 compilation failed to
>> produc
>> e executable
>>
>>  All instances of
>>
>> Excess errors:
>> Undefined                       first referenced
>> symbol                             in file
>> operator new(unsigned int, std::align_val_t) /var/tmp//cc_0Nrkd.o
>> ld: fatal: symbol referencing errors
>>
>>  libsupc++/new_opa.o contains
>>
>>  _ZnwjSt11align_val_t (operator new(unsigned int, std::align_val_t))
>>
>>  while for 64-bit there is
>>
>>  _ZnwmSt11align_val_t (operator new(unsigned long, std::align_val_t))
>>
>>  The former isn't matched by config/abi/pre/gnu.ver
>>
>>    # C++17 aligned new/delete
>>    _ZnwmSt11align_val_t;
>>    _ZnwmSt11align_val_tRKSt9nothrow_t;
>>    _ZnamSt11align_val_t;
>>    _ZnamSt11align_val_tRKSt9nothrow_t;
>>
>>  I strongly suspects this needs to be
>>
>>  _Znw[jmy]* just as for regular new/delete.
>
> Yes, that's right. Patch approved if you want to change that (I won't
> be able to until tomorrow).

Applied:

[-- Attachment #2: jmy.diff --]
[-- Type: text/plain, Size: 1088 bytes --]

commit 977ca0b5c0ffed38a5f2ec74c9769ec64c351cac
Author: Jason Merrill <jason@redhat.com>
Date:   Mon Sep 12 12:32:50 2016 -0400

            * config/abi/pre/gnu.ver: Use [jmy] for size_t.

diff --git a/libstdc++-v3/config/abi/pre/gnu.ver b/libstdc++-v3/config/abi/pre/gnu.ver
index 9b5bb23..8b0f67b 100644
--- a/libstdc++-v3/config/abi/pre/gnu.ver
+++ b/libstdc++-v3/config/abi/pre/gnu.ver
@@ -2198,16 +2198,16 @@ CXXABI_1.3.11 {
     _ZNSt15__exception_ptr13exception_ptrC1EPv;
 
     # C++17 aligned new/delete
-    _ZnwmSt11align_val_t;
-    _ZnwmSt11align_val_tRKSt9nothrow_t;
-    _ZnamSt11align_val_t;
-    _ZnamSt11align_val_tRKSt9nothrow_t;
+    _Znw[jmy]St11align_val_t;
+    _Znw[jmy]St11align_val_tRKSt9nothrow_t;
+    _Zna[jmy]St11align_val_t;
+    _Zna[jmy]St11align_val_tRKSt9nothrow_t;
     _ZdlPvSt11align_val_t;
     _ZdlPvSt11align_val_tRKSt9nothrow_t;
-    _ZdlPvmSt11align_val_t;
+    _ZdlPv[jmy]St11align_val_t;
     _ZdaPvSt11align_val_t;
     _ZdaPvSt11align_val_tRKSt9nothrow_t;
-    _ZdaPvmSt11align_val_t;
+    _ZdaPv[jmy]St11align_val_t;
 
 } CXXABI_1.3.10;
 

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: RFA (libstdc++): PATCH to implement C++17 over-aligned new
  2016-09-11  7:09       ` Andreas Schwab
@ 2016-09-12 21:13         ` Jason Merrill
  2016-09-13  8:41           ` Christophe Lyon
  2016-09-13 12:37           ` Andreas Schwab
  0 siblings, 2 replies; 42+ messages in thread
From: Jason Merrill @ 2016-09-12 21:13 UTC (permalink / raw)
  To: Andreas Schwab; +Cc: Jonathan Wakely, libstdc++, gcc-patches List

[-- Attachment #1: Type: text/plain, Size: 1242 bytes --]

I'm checking in this patch, which should fix the remaining issues:

On Sat, Sep 10, 2016 at 2:14 PM, Andreas Schwab <schwab@linux-m68k.org> wrote:
> FAIL: g++.dg/cpp1z/aligned-new1.C   (test for excess errors)
> Excess errors:
> /daten/aranym/gcc/gcc-20160910/gcc/testsuite/g++.dg/cpp1z/aligned-new1.C:10:20: warning: requested alignment 64 is larger than 16 [-Wattributes]
> FAIL: g++.dg/cpp1z/aligned-new1.C   execution test
> FAIL: g++.dg/cpp1z/aligned-new4.C    (test for warnings, line 11)
> FAIL: g++.dg/cpp1z/aligned-new4.C   (test for excess errors)
> Excess errors:
> /daten/aranym/gcc/gcc-20160910/gcc/testsuite/g++.dg/cpp1z/aligned-new4.C:3:20: warning: requested alignment 64 is larger than 16 [-Wattributes]
> /daten/aranym/gcc/gcc-20160910/gcc/testsuite/g++.dg/cpp1z/aligned-new4.C:4:20: warning: requested alignment 64 is larger than 16 [-Wattributes]
> FAIL: g++.dg/cpp1z/aligned-new5.C  -std=gnu++11 (test for excess errors)
> Excess errors:
> aligned-new5.C:(.text+0xe): undefined reference to `operator new(unsigned int, std::align_val_t)'
>
> Andreas.
>
> --
> Andreas Schwab, schwab@linux-m68k.org
> GPG Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
> "And now for something completely different."

[-- Attachment #2: align.diff --]
[-- Type: text/plain, Size: 2126 bytes --]

commit da8e3c2d6ca085aeb815d741e4d858b1216473a1
Author: Jason Merrill <jason@redhat.com>
Date:   Mon Sep 12 15:01:06 2016 -0400

            Fix aligned-new tests on m68k.
    
            * c-common.c (check_cxx_fundamental_alignment_constraints): Fix
            bit/byte confusion, allow large alignment for types.

diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index 16f6548..b4f4d10 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -7836,8 +7836,7 @@ check_user_alignment (const_tree align, bool allow_zero)
   return i;
 }
 
-/* 
-   If in c++-11, check if the c++-11 alignment constraint with respect
+/* If in c++-11, check if the c++-11 alignment constraint with respect
    to fundamental alignment (in [dcl.align]) are satisfied.  If not in
    c++-11 mode, does nothing.
 
@@ -7862,7 +7861,7 @@ check_cxx_fundamental_alignment_constraints (tree node,
 					     int flags)
 {
   bool alignment_too_large_p = false;
-  unsigned requested_alignment = 1U << align_log;
+  unsigned requested_alignment = (1U << align_log) * BITS_PER_UNIT;
   unsigned max_align = 0;
 
   if ((!(flags & ATTR_FLAG_CXX11) && !warn_cxx_compat)
@@ -7906,15 +7905,19 @@ check_cxx_fundamental_alignment_constraints (tree node,
     }
   else if (TYPE_P (node))
     {
-      /* Let's be liberal for types.  */
-      if (requested_alignment > (max_align = BIGGEST_ALIGNMENT))
+      /* Let's be liberal for types.  BIGGEST_ALIGNMENT is the largest
+	 alignment a built-in type can require, MAX_OFILE_ALIGNMENT is the
+	 largest alignment the object file can represent, but a type that is
+	 only allocated dynamically could request even larger alignment.  So
+	 only limit type alignment to what TYPE_ALIGN can represent.  */
+      if (requested_alignment > (max_align = 8U << 28))
 	alignment_too_large_p = true;
     }
 
   if (alignment_too_large_p)
     pedwarn (input_location, OPT_Wattributes,
 	     "requested alignment %d is larger than %d",
-	     requested_alignment, max_align);
+	     requested_alignment / BITS_PER_UNIT, max_align / BITS_PER_UNIT);
 
   return !alignment_too_large_p;
 }

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: RFA (libstdc++): PATCH to implement C++17 over-aligned new
  2016-09-12 21:13         ` Jason Merrill
@ 2016-09-13  8:41           ` Christophe Lyon
  2016-09-13 12:37           ` Andreas Schwab
  1 sibling, 0 replies; 42+ messages in thread
From: Christophe Lyon @ 2016-09-13  8:41 UTC (permalink / raw)
  To: Jason Merrill
  Cc: Andreas Schwab, Jonathan Wakely, libstdc++, gcc-patches List

On 12 September 2016 at 22:57, Jason Merrill <jason@redhat.com> wrote:
> I'm checking in this patch, which should fix the remaining issues:
>

Hi Jason,

Since this commit (r240100), I'm seeing failures on:
  g++.dg/cpp0x/gen-attrs-21.C  -std=c++11 (test for excess errors)
  g++.dg/cpp0x/gen-attrs-21.C  -std=c++14 (test for excess errors)

on arm* targets.

Christophe


> On Sat, Sep 10, 2016 at 2:14 PM, Andreas Schwab <schwab@linux-m68k.org> wrote:
>> FAIL: g++.dg/cpp1z/aligned-new1.C   (test for excess errors)
>> Excess errors:
>> /daten/aranym/gcc/gcc-20160910/gcc/testsuite/g++.dg/cpp1z/aligned-new1.C:10:20: warning: requested alignment 64 is larger than 16 [-Wattributes]
>> FAIL: g++.dg/cpp1z/aligned-new1.C   execution test
>> FAIL: g++.dg/cpp1z/aligned-new4.C    (test for warnings, line 11)
>> FAIL: g++.dg/cpp1z/aligned-new4.C   (test for excess errors)
>> Excess errors:
>> /daten/aranym/gcc/gcc-20160910/gcc/testsuite/g++.dg/cpp1z/aligned-new4.C:3:20: warning: requested alignment 64 is larger than 16 [-Wattributes]
>> /daten/aranym/gcc/gcc-20160910/gcc/testsuite/g++.dg/cpp1z/aligned-new4.C:4:20: warning: requested alignment 64 is larger than 16 [-Wattributes]
>> FAIL: g++.dg/cpp1z/aligned-new5.C  -std=gnu++11 (test for excess errors)
>> Excess errors:
>> aligned-new5.C:(.text+0xe): undefined reference to `operator new(unsigned int, std::align_val_t)'
>>
>> Andreas.
>>
>> --
>> Andreas Schwab, schwab@linux-m68k.org
>> GPG Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
>> "And now for something completely different."

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: RFA (libstdc++): PATCH to implement C++17 over-aligned new
  2016-09-12 21:13         ` Jason Merrill
  2016-09-13  8:41           ` Christophe Lyon
@ 2016-09-13 12:37           ` Andreas Schwab
  2016-09-13 12:54             ` Jason Merrill
  1 sibling, 1 reply; 42+ messages in thread
From: Andreas Schwab @ 2016-09-13 12:37 UTC (permalink / raw)
  To: Jason Merrill; +Cc: Jonathan Wakely, libstdc++, gcc-patches List

On Sep 12 2016, Jason Merrill <jason@redhat.com> wrote:

> I'm checking in this patch, which should fix the remaining issues:

Unfortunatly that breaks a few other tests:

FAIL: g++.dg/cpp0x/alignas5.C  -std=c++11 (test for excess errors)
FAIL: g++.dg/cpp0x/alignas5.C  -std=c++14 (test for excess errors)
FAIL: g++.dg/cpp0x/gen-attrs-21.C  -std=c++11 (test for excess errors)
FAIL: g++.dg/cpp0x/gen-attrs-21.C  -std=c++14 (test for excess errors)
FAIL: g++.dg/cpp0x/gen-attrs-51.C  -std=c++11 (test for excess errors)
FAIL: g++.dg/cpp0x/gen-attrs-51.C  -std=c++14 (test for excess errors)
FAIL: g++.dg/cpp0x/gen-attrs-54.C  -std=c++11 (test for excess errors)
FAIL: g++.dg/cpp0x/gen-attrs-54.C  -std=c++14 (test for excess errors)
FAIL: g++.dg/ipa/devirt-33.C   (test for excess errors)
FAIL: g++.dg/lookup/name-clash11.C  -std=gnu++11 (test for excess errors)
FAIL: g++.dg/lookup/name-clash11.C  -std=gnu++14 (test for excess errors)
FAIL: g++.dg/pr67989.C   (test for excess errors)

They all fail with "warning: requested alignment %d is larger than 2
[-Wattributes]".

Andreas.

-- 
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: RFA (libstdc++): PATCH to implement C++17 over-aligned new
  2016-09-13 12:37           ` Andreas Schwab
@ 2016-09-13 12:54             ` Jason Merrill
  2016-09-13 13:18               ` Andreas Schwab
  0 siblings, 1 reply; 42+ messages in thread
From: Jason Merrill @ 2016-09-13 12:54 UTC (permalink / raw)
  To: Andreas Schwab; +Cc: Jonathan Wakely, libstdc++, gcc-patches List

[-- Attachment #1: Type: text/plain, Size: 1389 bytes --]

Does this help?

On Tue, Sep 13, 2016 at 8:32 AM, Andreas Schwab <schwab@linux-m68k.org> wrote:
> On Sep 12 2016, Jason Merrill <jason@redhat.com> wrote:
>
>> I'm checking in this patch, which should fix the remaining issues:
>
> Unfortunatly that breaks a few other tests:
>
> FAIL: g++.dg/cpp0x/alignas5.C  -std=c++11 (test for excess errors)
> FAIL: g++.dg/cpp0x/alignas5.C  -std=c++14 (test for excess errors)
> FAIL: g++.dg/cpp0x/gen-attrs-21.C  -std=c++11 (test for excess errors)
> FAIL: g++.dg/cpp0x/gen-attrs-21.C  -std=c++14 (test for excess errors)
> FAIL: g++.dg/cpp0x/gen-attrs-51.C  -std=c++11 (test for excess errors)
> FAIL: g++.dg/cpp0x/gen-attrs-51.C  -std=c++14 (test for excess errors)
> FAIL: g++.dg/cpp0x/gen-attrs-54.C  -std=c++11 (test for excess errors)
> FAIL: g++.dg/cpp0x/gen-attrs-54.C  -std=c++14 (test for excess errors)
> FAIL: g++.dg/ipa/devirt-33.C   (test for excess errors)
> FAIL: g++.dg/lookup/name-clash11.C  -std=gnu++11 (test for excess errors)
> FAIL: g++.dg/lookup/name-clash11.C  -std=gnu++14 (test for excess errors)
> FAIL: g++.dg/pr67989.C   (test for excess errors)
>
> They all fail with "warning: requested alignment %d is larger than 2
> [-Wattributes]".
>
> Andreas.
>
> --
> Andreas Schwab, schwab@linux-m68k.org
> GPG Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
> "And now for something completely different."

[-- Attachment #2: uhwi.diff --]
[-- Type: text/plain, Size: 1690 bytes --]

commit 113f925a58a37cb8f18cd9c7aeeb4c03f5fc6afe
Author: Jason Merrill <jason@redhat.com>
Date:   Tue Sep 13 08:46:06 2016 -0400

            * c-common.c (check_cxx_fundamental_alignment_constraints): Use
            unsigned HOST_WIDE_INT.

diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index 9b5e016..e3dc0f5 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -7861,8 +7861,9 @@ check_cxx_fundamental_alignment_constraints (tree node,
 					     int flags)
 {
   bool alignment_too_large_p = false;
-  unsigned requested_alignment = (1U << align_log) * BITS_PER_UNIT;
-  unsigned max_align = 0;
+  unsigned HOST_WIDE_INT requested_alignment
+    = (unsigned HOST_WIDE_INT)BITS_PER_UNIT << align_log;
+  unsigned HOST_WIDE_INT max_align = 0;
 
   if ((!(flags & ATTR_FLAG_CXX11) && !warn_cxx_compat)
       || (node == NULL_TREE || node == error_mark_node))
@@ -7910,14 +7911,15 @@ check_cxx_fundamental_alignment_constraints (tree node,
 	 largest alignment the object file can represent, but a type that is
 	 only allocated dynamically could request even larger alignment.  So
 	 only limit type alignment to what TYPE_ALIGN can represent.  */
-      if (requested_alignment > (max_align = 8U << 28))
+      if (requested_alignment > (max_align = (unsigned HOST_WIDE_INT)8 << 28))
 	alignment_too_large_p = true;
     }
 
   if (alignment_too_large_p)
     pedwarn (input_location, OPT_Wattributes,
 	     "requested alignment %d is larger than %d",
-	     requested_alignment / BITS_PER_UNIT, max_align / BITS_PER_UNIT);
+	     int(requested_alignment / BITS_PER_UNIT),
+	     int(max_align / BITS_PER_UNIT));
 
   return !alignment_too_large_p;
 }

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: RFA (libstdc++): PATCH to implement C++17 over-aligned new
  2016-09-10  7:03       ` Christophe Lyon
  2016-09-10 10:14         ` Marc Glisse
  2016-09-11  9:14         ` Christophe Lyon
@ 2016-09-13 13:04         ` Szabolcs Nagy
  2 siblings, 0 replies; 42+ messages in thread
From: Szabolcs Nagy @ 2016-09-13 13:04 UTC (permalink / raw)
  To: Christophe Lyon, Jason Merrill
  Cc: nd, Jonathan Wakely, libstdc++, gcc-patches List

On 10/09/16 07:59, Christophe Lyon wrote:
> On 9 September 2016 at 23:20, Jason Merrill <jason@redhat.com> wrote:
>> On Thu, Sep 8, 2016 at 7:06 AM, Jonathan Wakely <jwakely@redhat.com> wrote:
>>> On 08/09/16 09:10 +0200, Marc Glisse wrote:
>>>>
>>>> Do we want a generic fallback implementation (similar to
>>>> gcc/config/i386/gmm_malloc.h)? A windows version with _aligned_malloc /
>>>> _aligned_free would also be possible.
>>>
>>> Making it work for MinGW would be nice.
>>
>> OK, this is what I'm checking in; could someone test it on MinGW?
>>
>> Jason
> 
> Hi Jason,
> 
> I'm seeing problems on arm*linux: the tests aligned-new[1235].C fail to link:
> aligned-new5.C:(.text+0x14): undefined reference to `operator
> new(unsigned int, std::align_val_t)'
> 
> 
> On aarch64*-elf and arm-eabi (using newlib), I'm seeing:
> /gccsrc/libstdc++-v3/libsupc++/new_opa.cc:66: undefined reference to
> `aligned_alloc'
> 
> Am I missing something in my setup?
> 

fwiw, i also see cilk plus execution test failures on arm linux since this commit.
(they abort)

FAIL: c-c++-common/cilk-plus/CK/fib.c  -O1 execution test
FAIL: c-c++-common/cilk-plus/CK/fib.c  -g -O2 execution test
FAIL: c-c++-common/cilk-plus/CK/fib_init_expr_xy.c  -g execution test
FAIL: c-c++-common/cilk-plus/CK/fib_no_return.c  -O1  execution test
FAIL: g++.dg/cilk-plus/CK/for1.cc  -O1 -fcilkplus execution test
FAIL: g++.dg/cilk-plus/CK/for1.cc  -O3 -fcilkplus execution test
FAIL: g++.dg/cilk-plus/CK/for1.cc  -g -fcilkplus execution test
FAIL: g++.dg/cilk-plus/CK/for1.cc  -g -O2 -fcilkplus execution test

> Thanks,
> 
> Christophe
> 

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: RFA (libstdc++): PATCH to implement C++17 over-aligned new
  2016-09-13 12:54             ` Jason Merrill
@ 2016-09-13 13:18               ` Andreas Schwab
  2016-09-13 13:21                 ` Jason Merrill
  0 siblings, 1 reply; 42+ messages in thread
From: Andreas Schwab @ 2016-09-13 13:18 UTC (permalink / raw)
  To: Jason Merrill; +Cc: Jonathan Wakely, libstdc++, gcc-patches List

On Sep 13 2016, Jason Merrill <jason@redhat.com> wrote:

> Does this help?

Unfortunatly no.

Andreas.

-- 
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: RFA (libstdc++): PATCH to implement C++17 over-aligned new
  2016-09-13 13:18               ` Andreas Schwab
@ 2016-09-13 13:21                 ` Jason Merrill
  2016-09-14 12:13                   ` Andreas Schwab
  0 siblings, 1 reply; 42+ messages in thread
From: Jason Merrill @ 2016-09-13 13:21 UTC (permalink / raw)
  To: Andreas Schwab; +Cc: Jonathan Wakely, libstdc++, gcc-patches List

[-- Attachment #1: Type: text/plain, Size: 309 bytes --]

On Tue, Sep 13, 2016 at 9:03 AM, Andreas Schwab <schwab@linux-m68k.org> wrote:
> On Sep 13 2016, Jason Merrill <jason@redhat.com> wrote:
>
>> Does this help?
>
> Unfortunatly no.

It occurs to me that this function doesn't need to restrict types at
all.  I'm checking this in; hopefully it will do the trick.

[-- Attachment #2: type-align.diff --]
[-- Type: text/plain, Size: 1170 bytes --]

commit 0f7f6249a4120620c7944d709691425f1c8c7a8b
Author: Jason Merrill <jason@redhat.com>
Date:   Tue Sep 13 09:13:57 2016 -0400

            Trying again to fix aligned-new on m68k.
    
            * c-common.c (check_cxx_fundamental_alignment_constraints): Don't
            limit types at all.

diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index 9b5e016..9fec2cf 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -7905,13 +7905,8 @@ check_cxx_fundamental_alignment_constraints (tree node,
     }
   else if (TYPE_P (node))
     {
-      /* Let's be liberal for types.  BIGGEST_ALIGNMENT is the largest
-	 alignment a built-in type can require, MAX_OFILE_ALIGNMENT is the
-	 largest alignment the object file can represent, but a type that is
-	 only allocated dynamically could request even larger alignment.  So
-	 only limit type alignment to what TYPE_ALIGN can represent.  */
-      if (requested_alignment > (max_align = 8U << 28))
-	alignment_too_large_p = true;
+      /* Let's be liberal for types; don't limit their alignment any more than
+	 check_user_alignment already did.  */
     }
 
   if (alignment_too_large_p)

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: RFA (libstdc++): PATCH to implement C++17 over-aligned new
  2016-09-12 16:19         ` Jonathan Wakely
  2016-09-12 18:57           ` Jason Merrill
@ 2016-09-14 12:11           ` Rainer Orth
  1 sibling, 0 replies; 42+ messages in thread
From: Rainer Orth @ 2016-09-14 12:11 UTC (permalink / raw)
  To: Jonathan Wakely; +Cc: Jason Merrill, libstdc++, gcc-patches List

Hi Jonathan,

>>* For 64-bit, I get
>>
>>+FAIL: g++.dg/cpp1z/aligned-new5.C  -std=gnu++11 execution test
>>+FAIL: g++.dg/cpp1z/aligned-new5.C  -std=gnu++14 execution test
>>+FAIL: g++.dg/cpp1z/aligned-new5.C  -std=gnu++98 execution test
>>
>>  which fails like this:
>>
>>terminate called after throwing an instance of 'std::bad_alloc'
>>  what():  std::bad_alloc
>>
>>  gdb shows
>>
>>#7  0xffff80ff1d104bdc in __cxxabiv1::__cxa_throw (obj=<optimized out>,
>>    tinfo=0xffff80ff1d2d0c98 <typeinfo for std::bad_alloc>,
>>    dest=0xffff80ff1d1028f0 <std::bad_alloc::~bad_alloc()>)
>>    at /vol/gcc/src/hg/trunk/local/libstdc++-v3/libsupc++/eh_throw.cc:96
>>#8  0xffff80ff1d10604c in operator new (sz=4, al=(unknown: 64))
>>    at /vol/gcc/src/hg/trunk/local/libstdc++-v3/libsupc++/new_opa.cc:71
>>#9  0x00000000004010df in main ()
>>    at /vol/gcc/src/hg/trunk/local/gcc/testsuite/g++.dg/cpp1z/aligned-new5.C:11
>>
>>  and aligned_alloc(3C) documents
>>
>>       The  value of alignment must be a valid alignment supported by the sys-
>>       tem, that is, any power of two (1, 2, 4, 8, ...), and the value of size
>>       must be an integral multiple of alignment.
>>
>>  which isn't the case here.
>
> Ah, it seems GNU's aligned_alloc doesn't check that requirement. So we
> need to increase the requested size, maybe something like this patch.

I've now tested this patch on top of r240127 and the execution failures
are gone indeed.

The only failures now remaining are (on 32-bit sparc-sun-solaris2.12,
both 64-bit sparc and 32/64-bit i386-pc-solaris2.12 are fine)

FAIL: g++.dg/cpp0x/gen-attrs-21.C  -std=c++11 (test for excess errors)
FAIL: g++.dg/cpp0x/gen-attrs-21.C  -std=c++14 (test for excess errors)

Excess errors:
/vol/gcc/src/hg/trunk/local/gcc/testsuite/g++.dg/cpp0x/gen-attrs-21.C:9:31: error: requested alignment 16 is larger than 8 [-Wattributes]
/vol/gcc/src/hg/trunk/local/gcc/testsuite/g++.dg/cpp0x/gen-attrs-21.C:15:32: error: requested alignment 16 is larger than 8 [-Wattributes]
/vol/gcc/src/hg/trunk/local/gcc/testsuite/g++.dg/cpp0x/gen-attrs-21.C:21:1: error: static assertion failed: sizeof (S) == 8 + 16 + 8

FAIL: g++.dg/cpp0x/gen-attrs-51.C  -std=c++11 (test for excess errors)
FAIL: g++.dg/cpp0x/gen-attrs-51.C  -std=c++14 (test for excess errors)

Excess errors:
/vol/gcc/src/hg/trunk/local/gcc/testsuite/g++.dg/cpp0x/gen-attrs-51.C:6:44: error: requested alignment 16 is larger than 8 [-Wattributes]
/vol/gcc/src/hg/trunk/local/gcc/testsuite/g++.dg/cpp0x/gen-attrs-51.C:9:1: error: static assertion failed: Alignment should be 16

FAIL: g++.dg/ipa/devirt-33.C   (test for excess errors)

Excess errors:
/vol/gcc/src/hg/trunk/local/gcc/testsuite/g++.dg/ipa/devirt-33.C:46:32: warning: requested alignment 16 is larger than 8 [-Wattributes]

FAIL: g++.dg/lookup/name-clash11.C  -std=gnu++11 (test for excess errors)
FAIL: g++.dg/lookup/name-clash11.C  -std=gnu++14 (test for excess errors)

Excess errors:
/vol/gcc/src/hg/trunk/local/gcc/testsuite/g++.dg/lookup/name-clash11.C:51:11: warning: requested alignment 16 is larger than 8 [-Wattributes]
/vol/gcc/src/hg/trunk/local/gcc/testsuite/g++.dg/lookup/name-clash11.C:7:21: error: static assertion failed: __alignof__ (this->A) == 16

FAIL: 29_atomics/atomic/65147.cc (test for excess errors)

Excess errors:
/vol/gcc/src/hg/trunk/local/libstdc++-v3/testsuite/29_atomics/atomic/65147.cc:26: error: static assertion failed: atomic<S16> must be aligned to at least its size

Thanks.
	Rainer

-- 
-----------------------------------------------------------------------------
Rainer Orth, Center for Biotechnology, Bielefeld University

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: RFA (libstdc++): PATCH to implement C++17 over-aligned new
  2016-09-13 13:21                 ` Jason Merrill
@ 2016-09-14 12:13                   ` Andreas Schwab
  2016-09-14 16:11                     ` Christophe Lyon
  0 siblings, 1 reply; 42+ messages in thread
From: Andreas Schwab @ 2016-09-14 12:13 UTC (permalink / raw)
  To: Jason Merrill; +Cc: Jonathan Wakely, libstdc++, gcc-patches List

On Sep 13 2016, Jason Merrill <jason@redhat.com> wrote:

> On Tue, Sep 13, 2016 at 9:03 AM, Andreas Schwab <schwab@linux-m68k.org> wrote:
>> On Sep 13 2016, Jason Merrill <jason@redhat.com> wrote:
>>
>>> Does this help?
>>
>> Unfortunatly no.
>
> It occurs to me that this function doesn't need to restrict types at
> all.  I'm checking this in; hopefully it will do the trick.

That didn't change anything either.

Andreas.

-- 
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: RFA (libstdc++): PATCH to implement C++17 over-aligned new
  2016-09-14 12:13                   ` Andreas Schwab
@ 2016-09-14 16:11                     ` Christophe Lyon
  2016-09-14 16:37                       ` Jason Merrill
  0 siblings, 1 reply; 42+ messages in thread
From: Christophe Lyon @ 2016-09-14 16:11 UTC (permalink / raw)
  To: Andreas Schwab
  Cc: Jason Merrill, Jonathan Wakely, libstdc++, gcc-patches List

On 14 September 2016 at 14:11, Andreas Schwab <schwab@linux-m68k.org> wrote:
> On Sep 13 2016, Jason Merrill <jason@redhat.com> wrote:
>
>> On Tue, Sep 13, 2016 at 9:03 AM, Andreas Schwab <schwab@linux-m68k.org> wrote:
>>> On Sep 13 2016, Jason Merrill <jason@redhat.com> wrote:
>>>
>>>> Does this help?
>>>
>>> Unfortunatly no.
>>
>> It occurs to me that this function doesn't need to restrict types at
>> all.  I'm checking this in; hopefully it will do the trick.
>
> That didn't change anything either.
>

I confirm no change on arm* either.
On aarch64, gen-attrs-[25]1.C, and devirt-33 now work.
name-clash11.C still fails on both targets

Thanks,

Christophe

> Andreas.
>
> --
> Andreas Schwab, schwab@linux-m68k.org
> GPG Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
> "And now for something completely different."

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: RFA (libstdc++): PATCH to implement C++17 over-aligned new
  2016-09-14 16:11                     ` Christophe Lyon
@ 2016-09-14 16:37                       ` Jason Merrill
  2016-09-15 10:00                         ` Rainer Orth
  0 siblings, 1 reply; 42+ messages in thread
From: Jason Merrill @ 2016-09-14 16:37 UTC (permalink / raw)
  To: Christophe Lyon
  Cc: Andreas Schwab, Jonathan Wakely, libstdc++, gcc-patches List

[-- Attachment #1: Type: text/plain, Size: 842 bytes --]

On Wed, Sep 14, 2016 at 12:08 PM, Christophe Lyon
<christophe.lyon@linaro.org> wrote:
> On 14 September 2016 at 14:11, Andreas Schwab <schwab@linux-m68k.org> wrote:
>> On Sep 13 2016, Jason Merrill <jason@redhat.com> wrote:
>>
>>> On Tue, Sep 13, 2016 at 9:03 AM, Andreas Schwab <schwab@linux-m68k.org> wrote:
>>>> On Sep 13 2016, Jason Merrill <jason@redhat.com> wrote:
>>>>
>>>>> Does this help?
>>>>
>>>> Unfortunatly no.
>>>
>>> It occurs to me that this function doesn't need to restrict types at
>>> all.  I'm checking this in; hopefully it will do the trick.
>>
>> That didn't change anything either.
>>
>
> I confirm no change on arm* either.
> On aarch64, gen-attrs-[25]1.C, and devirt-33 now work.
> name-clash11.C still fails on both targets

Ah, I needed to remove the limit on field alignment as well.  This
seems to fix things.

[-- Attachment #2: field-align.diff --]
[-- Type: text/plain, Size: 3633 bytes --]

commit 367afdb008cfb122e9bb2c73ba0a8d8b29a738c0
Author: Jason Merrill <jason@redhat.com>
Date:   Wed Sep 14 11:12:09 2016 -0400

            * c-common.c (check_cxx_fundamental_alignment_constraints): Don't
            limit FIELD_DECL, either.

diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index b561f9f..57b6671 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -7868,43 +7868,21 @@ check_cxx_fundamental_alignment_constraints (tree node,
   if (cxx_fundamental_alignment_p (requested_alignment))
     return true;
 
-  if (DECL_P (node))
+  if (VAR_P (node))
     {
       if (TREE_STATIC (node))
-	{
-	  /* For file scope variables and static members, the target
-	     supports alignments that are at most
-	     MAX_OFILE_ALIGNMENT.  */
-	  if (requested_alignment > (max_align = MAX_OFILE_ALIGNMENT))
-	    alignment_too_large_p = true;
-	}
+	/* For file scope variables and static members, the target supports
+	   alignments that are at most MAX_OFILE_ALIGNMENT.  */
+	max_align = MAX_OFILE_ALIGNMENT;
       else
-	{
-#ifdef BIGGEST_FIELD_ALIGNMENT
-#define MAX_TARGET_FIELD_ALIGNMENT BIGGEST_FIELD_ALIGNMENT
-#else
-#define MAX_TARGET_FIELD_ALIGNMENT BIGGEST_ALIGNMENT
-#endif
-	  /* For non-static members, the target supports either
-	     alignments that at most either BIGGEST_FIELD_ALIGNMENT
-	     if it is defined or BIGGEST_ALIGNMENT.  */
-	  max_align = MAX_TARGET_FIELD_ALIGNMENT;
-	  if (TREE_CODE (node) == FIELD_DECL
-	      && requested_alignment > (max_align = MAX_TARGET_FIELD_ALIGNMENT))
-	    alignment_too_large_p = true;
-#undef MAX_TARGET_FIELD_ALIGNMENT
-	  /* For stack variables, the target supports at most
-	     MAX_STACK_ALIGNMENT.  */
-	  else if (decl_function_context (node) != NULL
-		   && requested_alignment > (max_align = MAX_STACK_ALIGNMENT))
-	    alignment_too_large_p = true;
-	}
-    }
-  else if (TYPE_P (node))
-    {
-      /* Let's be liberal for types; don't limit their alignment any more than
-	 check_user_alignment already did.  */
+	/* For stack variables, the target supports at most
+	   MAX_STACK_ALIGNMENT.  */
+	max_align = MAX_STACK_ALIGNMENT;
+      if (requested_alignment > max_align)
+	alignment_too_large_p = true;
     }
+  /* Let's be liberal for types and fields; don't limit their alignment any
+     more than check_user_alignment already did.  */
 
   if (alignment_too_large_p)
     pedwarn (input_location, OPT_Wattributes,
diff --git a/gcc/testsuite/g++.dg/cpp0x/gen-attrs-52.C b/gcc/testsuite/g++.dg/cpp0x/gen-attrs-52.C
index 0f87fd4..ad7cffc 100644
--- a/gcc/testsuite/g++.dg/cpp0x/gen-attrs-52.C
+++ b/gcc/testsuite/g++.dg/cpp0x/gen-attrs-52.C
@@ -3,19 +3,22 @@
 struct A {int i;}  a [[gnu::aligned(16)]];
 struct B {int i;} __attribute__((aligned(16))) b;
 
+constexpr unsigned si = sizeof(int);
+constexpr unsigned ai = alignof(int);
+
 int
 main ()
 {
  A aa;
  B bb;
 
- static_assert (sizeof (a) == 4, "sizeof (a) should be 4");
+ static_assert (sizeof (a) == si, "sizeof (a) should be 4");
  static_assert (sizeof (b) == 16, "sizeof (b) should be 16");
- static_assert (sizeof (aa) == 4, "sizeof (aa) should be 4");
+ static_assert (sizeof (aa) == si, "sizeof (aa) should be 4");
  static_assert (sizeof (bb) == 16, "sizeof (bb) should be 16");
 
  static_assert (__alignof__  (a) == 16, "alignof (a) should be 16");
  static_assert (__alignof__  (b) == 16, "alignof (b) should be 16");
- static_assert (__alignof__  (aa) == 4, "alignof (aa) should be 4");
+ static_assert (__alignof__  (aa) == ai, "alignof (aa) should be 4");
  static_assert (__alignof__  (bb) == 16, "alignof (bb) should be 16");
 }

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: RFA (libstdc++): PATCH to implement C++17 over-aligned new
  2016-09-14 16:37                       ` Jason Merrill
@ 2016-09-15 10:00                         ` Rainer Orth
  2016-09-15 12:23                           ` Christophe Lyon
  0 siblings, 1 reply; 42+ messages in thread
From: Rainer Orth @ 2016-09-15 10:00 UTC (permalink / raw)
  To: Jason Merrill
  Cc: Christophe Lyon, Andreas Schwab, Jonathan Wakely, libstdc++,
	gcc-patches List

Hi Jason,

>> I confirm no change on arm* either.
>> On aarch64, gen-attrs-[25]1.C, and devirt-33 now work.
>> name-clash11.C still fails on both targets
>
> Ah, I needed to remove the limit on field alignment as well.  This
> seems to fix things.

The failures are gone on Solaris/SPARC (sparc-sun-solaris2.12) now, with
one exception (when run as C test):

32-bit:

FAIL: c-c++-common/pr52181.c  -Wc++-compat   (test for bogus messages, line 11)
FAIL: c-c++-common/pr52181.c  -Wc++-compat  (test for excess errors)

This is new with you last patch.

Excess errors:
/vol/gcc/src/hg/trunk/local/gcc/testsuite/c-c++-common/pr52181.c:6:1: warning: requested alignment 16 is larger than 8 [-Wattributes]
/vol/gcc/src/hg/trunk/local/gcc/testsuite/c-c++-common/pr52181.c:8:1: warning: requested alignment 16 is larger than 8 [-Wattributes]

	Rainer

-- 
-----------------------------------------------------------------------------
Rainer Orth, Center for Biotechnology, Bielefeld University

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: RFA (libstdc++): PATCH to implement C++17 over-aligned new
  2016-09-15 10:00                         ` Rainer Orth
@ 2016-09-15 12:23                           ` Christophe Lyon
  2016-09-15 20:09                             ` Jason Merrill
  0 siblings, 1 reply; 42+ messages in thread
From: Christophe Lyon @ 2016-09-15 12:23 UTC (permalink / raw)
  To: Rainer Orth
  Cc: Jason Merrill, Andreas Schwab, Jonathan Wakely, libstdc++,
	gcc-patches List

On 15 September 2016 at 11:26, Rainer Orth <ro@cebitec.uni-bielefeld.de> wrote:
> Hi Jason,
>
>>> I confirm no change on arm* either.
>>> On aarch64, gen-attrs-[25]1.C, and devirt-33 now work.
>>> name-clash11.C still fails on both targets
>>
>> Ah, I needed to remove the limit on field alignment as well.  This
>> seems to fix things.
>
> The failures are gone on Solaris/SPARC (sparc-sun-solaris2.12) now, with
> one exception (when run as C test):
>
> 32-bit:
>
> FAIL: c-c++-common/pr52181.c  -Wc++-compat   (test for bogus messages, line 11)
> FAIL: c-c++-common/pr52181.c  -Wc++-compat  (test for excess errors)
>

Hi Jason,

Same on arm* if that's easier for you.

Christophe


> This is new with you last patch.
>
> Excess errors:
> /vol/gcc/src/hg/trunk/local/gcc/testsuite/c-c++-common/pr52181.c:6:1: warning: requested alignment 16 is larger than 8 [-Wattributes]
> /vol/gcc/src/hg/trunk/local/gcc/testsuite/c-c++-common/pr52181.c:8:1: warning: requested alignment 16 is larger than 8 [-Wattributes]
>
>         Rainer
>
> --
> -----------------------------------------------------------------------------
> Rainer Orth, Center for Biotechnology, Bielefeld University

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: RFA (libstdc++): PATCH to implement C++17 over-aligned new
  2016-09-15 12:23                           ` Christophe Lyon
@ 2016-09-15 20:09                             ` Jason Merrill
  2016-09-16  7:12                               ` Rainer Orth
  0 siblings, 1 reply; 42+ messages in thread
From: Jason Merrill @ 2016-09-15 20:09 UTC (permalink / raw)
  To: Christophe Lyon
  Cc: Rainer Orth, Andreas Schwab, Jonathan Wakely, libstdc++,
	gcc-patches List

[-- Attachment #1: Type: text/plain, Size: 1321 bytes --]

OK, one more:

On Thu, Sep 15, 2016 at 8:12 AM, Christophe Lyon
<christophe.lyon@linaro.org> wrote:
> On 15 September 2016 at 11:26, Rainer Orth <ro@cebitec.uni-bielefeld.de> wrote:
>> Hi Jason,
>>
>>>> I confirm no change on arm* either.
>>>> On aarch64, gen-attrs-[25]1.C, and devirt-33 now work.
>>>> name-clash11.C still fails on both targets
>>>
>>> Ah, I needed to remove the limit on field alignment as well.  This
>>> seems to fix things.
>>
>> The failures are gone on Solaris/SPARC (sparc-sun-solaris2.12) now, with
>> one exception (when run as C test):
>>
>> 32-bit:
>>
>> FAIL: c-c++-common/pr52181.c  -Wc++-compat   (test for bogus messages, line 11)
>> FAIL: c-c++-common/pr52181.c  -Wc++-compat  (test for excess errors)
>>
>
> Hi Jason,
>
> Same on arm* if that's easier for you.
>
> Christophe
>
>
>> This is new with you last patch.
>>
>> Excess errors:
>> /vol/gcc/src/hg/trunk/local/gcc/testsuite/c-c++-common/pr52181.c:6:1: warning: requested alignment 16 is larger than 8 [-Wattributes]
>> /vol/gcc/src/hg/trunk/local/gcc/testsuite/c-c++-common/pr52181.c:8:1: warning: requested alignment 16 is larger than 8 [-Wattributes]
>>
>>         Rainer
>>
>> --
>> -----------------------------------------------------------------------------
>> Rainer Orth, Center for Biotechnology, Bielefeld University

[-- Attachment #2: align-ext.diff --]
[-- Type: text/plain, Size: 745 bytes --]

commit 1a1beb3ab1279f83d411e96d7b5abbf7875c7956
Author: Jason Merrill <jason@redhat.com>
Date:   Thu Sep 15 12:30:03 2016 -0400

            * c-common.c (check_cxx_fundamental_alignment_constraints): Check
            DECL_EXTERNAL.

diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index 57b6671..fc25686 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -7870,7 +7870,7 @@ check_cxx_fundamental_alignment_constraints (tree node,
 
   if (VAR_P (node))
     {
-      if (TREE_STATIC (node))
+      if (TREE_STATIC (node) || DECL_EXTERNAL (node))
 	/* For file scope variables and static members, the target supports
 	   alignments that are at most MAX_OFILE_ALIGNMENT.  */
 	max_align = MAX_OFILE_ALIGNMENT;

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: RFA (libstdc++): PATCH to implement C++17 over-aligned new
  2016-09-15 20:09                             ` Jason Merrill
@ 2016-09-16  7:12                               ` Rainer Orth
  2016-09-16  8:15                                 ` Christophe Lyon
  2016-09-16  9:14                                 ` Jonathan Wakely
  0 siblings, 2 replies; 42+ messages in thread
From: Rainer Orth @ 2016-09-16  7:12 UTC (permalink / raw)
  To: Jason Merrill
  Cc: Christophe Lyon, Andreas Schwab, Jonathan Wakely, libstdc++,
	gcc-patches List

Hi Jason,

> OK, one more:

this works just fine on both sparc-sun-solaris2.12 and
i386-pc-solaris2.12.

Once Jonathan's patch to heed aligned_alloc's requirement on size being
a multiple of alignment is in, all is fine on Solaris.

Thanks.
	Rainer

-- 
-----------------------------------------------------------------------------
Rainer Orth, Center for Biotechnology, Bielefeld University

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: RFA (libstdc++): PATCH to implement C++17 over-aligned new
  2016-09-16  7:12                               ` Rainer Orth
@ 2016-09-16  8:15                                 ` Christophe Lyon
  2016-09-16  9:14                                 ` Jonathan Wakely
  1 sibling, 0 replies; 42+ messages in thread
From: Christophe Lyon @ 2016-09-16  8:15 UTC (permalink / raw)
  To: Rainer Orth
  Cc: Jason Merrill, Andreas Schwab, Jonathan Wakely, libstdc++,
	gcc-patches List

On 16 September 2016 at 09:04, Rainer Orth <ro@cebitec.uni-bielefeld.de> wrote:
> Hi Jason,
>
>> OK, one more:
>
> this works just fine on both sparc-sun-solaris2.12 and
> i386-pc-solaris2.12.
>
> Once Jonathan's patch to heed aligned_alloc's requirement on size being
> a multiple of alignment is in, all is fine on Solaris.
>
> Thanks.
>         Rainer
>

It looks OK on arm now too, thanks.

Christophe

> --
> -----------------------------------------------------------------------------
> Rainer Orth, Center for Biotechnology, Bielefeld University

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: RFA (libstdc++): PATCH to implement C++17 over-aligned new
  2016-09-16  7:12                               ` Rainer Orth
  2016-09-16  8:15                                 ` Christophe Lyon
@ 2016-09-16  9:14                                 ` Jonathan Wakely
  2016-09-16  9:51                                   ` Marc Glisse
  1 sibling, 1 reply; 42+ messages in thread
From: Jonathan Wakely @ 2016-09-16  9:14 UTC (permalink / raw)
  To: Rainer Orth
  Cc: Jason Merrill, Christophe Lyon, Andreas Schwab, libstdc++,
	gcc-patches List

[-- Attachment #1: Type: text/plain, Size: 684 bytes --]

On 16/09/16 09:04 +0200, Rainer Orth wrote:
>Hi Jason,
>
>> OK, one more:
>
>this works just fine on both sparc-sun-solaris2.12 and
>i386-pc-solaris2.12.
>
>Once Jonathan's patch to heed aligned_alloc's requirement on size being
>a multiple of alignment is in, all is fine on Solaris.

I've got a slightly different fix now.

We only need to make the size a multiple of alignment for
aligned_alloc, however for posix_memalign we need to ensure the
alignment is a multiple of sizeof(void*).

I'm testing this now (but only on x86_64 GNU/Linux where it wasn't
failing anyway).

Would using __builtin_expect (sz == 0, false) make sense?  Surely it's
rare to try to allocate zero bytes.


[-- Attachment #2: patch.txt --]
[-- Type: text/x-patch, Size: 1623 bytes --]

commit 216b9547230295e615bab86aaede65554f63e57d
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Fri Sep 16 09:54:51 2016 +0100

    Adjust arguments to aligned_alloc or posix_memalign
    
    	* libsupc++/new_opa.cc [_GLIBCXX_HAVE_POSIX_MEMALIGN] (aligned_alloc):
    	Increase alignment if less than sizeof(void*).
    	[_GLIBCXX_HAVE_ALIGNED_ALLOC] (operator new(size_t, align_val_t)):
    	Increase size if not a multiple of alignment.

diff --git a/libstdc++-v3/libsupc++/new_opa.cc b/libstdc++-v3/libsupc++/new_opa.cc
index 6ff5421..9c859c1 100644
--- a/libstdc++-v3/libsupc++/new_opa.cc
+++ b/libstdc++-v3/libsupc++/new_opa.cc
@@ -39,6 +39,9 @@ static inline void*
 aligned_alloc (std::size_t al, std::size_t sz)
 {
   void *ptr;
+  // The value of alignment shall be a power of two multiple of sizeof(void *).
+  if (al < sizeof(void*))
+    al = sizeof(void*);
   int ret = posix_memalign (&ptr, al, sz);
   if (ret == 0)
     return ptr;
@@ -58,13 +61,19 @@ _GLIBCXX_WEAK_DEFINITION void *
 operator new (std::size_t sz, std::align_val_t al)
 {
   void *p;
+  std::size_t align = (std::size_t)al;
 
   /* malloc (0) is unpredictable; avoid it.  */
   if (sz == 0)
     sz = 1;
 
-  while (__builtin_expect ((p = aligned_alloc ((std::size_t)al, sz)) == 0,
-			   false))
+#if _GLIBCXX_HAVE_ALIGNED_ALLOC
+  /* C11: the value of size shall be an integral multiple of alignment.  */
+  if (std::size_t rem = sz % align)
+    sz += align - rem;
+#endif
+
+  while (__builtin_expect ((p = aligned_alloc (align, sz)) == 0, false))
     {
       new_handler handler = std::get_new_handler ();
       if (! handler)

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: RFA (libstdc++): PATCH to implement C++17 over-aligned new
  2016-09-16  9:14                                 ` Jonathan Wakely
@ 2016-09-16  9:51                                   ` Marc Glisse
  2016-09-16 11:12                                     ` Jonathan Wakely
  0 siblings, 1 reply; 42+ messages in thread
From: Marc Glisse @ 2016-09-16  9:51 UTC (permalink / raw)
  To: Jonathan Wakely
  Cc: Rainer Orth, Jason Merrill, Christophe Lyon, Andreas Schwab,
	libstdc++,
	gcc-patches List

On Fri, 16 Sep 2016, Jonathan Wakely wrote:

> On 16/09/16 09:04 +0200, Rainer Orth wrote:
>> Hi Jason,
>> 
>>> OK, one more:
>> 
>> this works just fine on both sparc-sun-solaris2.12 and
>> i386-pc-solaris2.12.
>> 
>> Once Jonathan's patch to heed aligned_alloc's requirement on size being
>> a multiple of alignment is in, all is fine on Solaris.
>
> I've got a slightly different fix now.
>
> We only need to make the size a multiple of alignment for
> aligned_alloc, however for posix_memalign we need to ensure the
> alignment is a multiple of sizeof(void*).
>
> I'm testing this now (but only on x86_64 GNU/Linux where it wasn't
> failing anyway).

+  // The value of alignment shall be a power of two multiple of sizeof(void *).
+  if (al < sizeof(void*))
+    al = sizeof(void*);

The code doesn't exactly match the comment. I can't find the precondition 
in the standard that says operator new can only be called on a power of 
2... (maybe we can add it if it is really missing?)

> Would using __builtin_expect (sz == 0, false) make sense?  Surely it's
> rare to try to allocate zero bytes.

https://gcc.gnu.org/ml/libstdc++/2014-03/msg00001.html

gcc already guesses that a test like sz == 0 is usually false (not with as 
large a probability as if you use __builtin_expect, but enough that the 
generated code is unlikely to differ). But adding __builtin_expect cannot 
hurt...

Is the division (by a non-constant denominator) really necessary? Since 
align has to be a power of 2, x % align should be the same as x & (align - 
1), for instance.

I guess people interested in performance will do for aligned new the same 
as for the old new: provide an inline version that skips all the overhead 
to forward directly to malloc/aligned_alloc (and avoid questionable calls 
in their code).

-- 
Marc Glisse

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: RFA (libstdc++): PATCH to implement C++17 over-aligned new
  2016-09-16  9:51                                   ` Marc Glisse
@ 2016-09-16 11:12                                     ` Jonathan Wakely
  2016-09-16 13:13                                       ` Jonathan Wakely
  0 siblings, 1 reply; 42+ messages in thread
From: Jonathan Wakely @ 2016-09-16 11:12 UTC (permalink / raw)
  To: libstdc++
  Cc: Rainer Orth, Jason Merrill, Christophe Lyon, Andreas Schwab,
	gcc-patches List

On 16/09/16 11:37 +0200, Marc Glisse wrote:
>On Fri, 16 Sep 2016, Jonathan Wakely wrote:
>
>>On 16/09/16 09:04 +0200, Rainer Orth wrote:
>>>Hi Jason,
>>>
>>>>OK, one more:
>>>
>>>this works just fine on both sparc-sun-solaris2.12 and
>>>i386-pc-solaris2.12.
>>>
>>>Once Jonathan's patch to heed aligned_alloc's requirement on size being
>>>a multiple of alignment is in, all is fine on Solaris.
>>
>>I've got a slightly different fix now.
>>
>>We only need to make the size a multiple of alignment for
>>aligned_alloc, however for posix_memalign we need to ensure the
>>alignment is a multiple of sizeof(void*).
>>
>>I'm testing this now (but only on x86_64 GNU/Linux where it wasn't
>>failing anyway).
>
>+  // The value of alignment shall be a power of two multiple of sizeof(void *).
>+  if (al < sizeof(void*))
>+    al = sizeof(void*);
>
>The code doesn't exactly match the comment. I can't find the 
>precondition in the standard that says operator new can only be called 
>on a power of 2... (maybe we can add it if it is really missing?)

[basic.align] says "Every alignment value shall be a non-negative
integral power of two." So asking operator new for any other value
doesn't make sense, but I can't find a restriction on doing so.

I was assuming we only need to ensure it's possible to use valid
alignments such as align_val_t(2) which are not valid arguments to
posix_memalign. For other values such as align_val_t(15) I was
assuming it's OK for posix_memalign to fail, so we throw bad_alloc.

If that's not the case then we need to round up all alignments that
aren't power of two multiples of sizeof(void*). I'd like to avoid
that.

>>Would using __builtin_expect (sz == 0, false) make sense?  Surely it's
>>rare to try to allocate zero bytes.
>
>https://gcc.gnu.org/ml/libstdc++/2014-03/msg00001.html
>
>gcc already guesses that a test like sz == 0 is usually false (not 
>with as large a probability as if you use __builtin_expect, but enough 
>that the generated code is unlikely to differ). But adding 
>__builtin_expect cannot hurt...
>
>Is the division (by a non-constant denominator) really necessary? 

Probably not, but I've asked the committee for clarification what this
function should do when called with an invalid alignment.

>Since align has to be a power of 2, x % align should be the same as x 
>& (align - 1), for instance.

Thanks, if it's UB to call it with alignments that aren't a power of
two then we can do that.

>I guess people interested in performance will do for aligned new the 
>same as for the old new: provide an inline version that skips all the 
>overhead to forward directly to malloc/aligned_alloc (and avoid 
>questionable calls in their code).
>
>-- 
>Marc Glisse

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: RFA (libstdc++): PATCH to implement C++17 over-aligned new
  2016-09-16 11:12                                     ` Jonathan Wakely
@ 2016-09-16 13:13                                       ` Jonathan Wakely
  2016-09-16 13:17                                         ` Rainer Orth
  2016-09-16 18:19                                         ` Jonathan Wakely
  0 siblings, 2 replies; 42+ messages in thread
From: Jonathan Wakely @ 2016-09-16 13:13 UTC (permalink / raw)
  To: libstdc++
  Cc: Rainer Orth, Jason Merrill, Christophe Lyon, Andreas Schwab,
	gcc-patches List

On 16/09/16 11:56 +0100, Jonathan Wakely wrote:
>On 16/09/16 11:37 +0200, Marc Glisse wrote:
>>On Fri, 16 Sep 2016, Jonathan Wakely wrote:
>>
>>>On 16/09/16 09:04 +0200, Rainer Orth wrote:
>>>>Hi Jason,
>>>>
>>>>>OK, one more:
>>>>
>>>>this works just fine on both sparc-sun-solaris2.12 and
>>>>i386-pc-solaris2.12.
>>>>
>>>>Once Jonathan's patch to heed aligned_alloc's requirement on size being
>>>>a multiple of alignment is in, all is fine on Solaris.
>>>
>>>I've got a slightly different fix now.
>>>
>>>We only need to make the size a multiple of alignment for
>>>aligned_alloc, however for posix_memalign we need to ensure the
>>>alignment is a multiple of sizeof(void*).
>>>
>>>I'm testing this now (but only on x86_64 GNU/Linux where it wasn't
>>>failing anyway).
>>
>>+  // The value of alignment shall be a power of two multiple of sizeof(void *).
>>+  if (al < sizeof(void*))
>>+    al = sizeof(void*);
>>
>>The code doesn't exactly match the comment. I can't find the 
>>precondition in the standard that says operator new can only be 
>>called on a power of 2... (maybe we can add it if it is really 
>>missing?)
>
>[basic.align] says "Every alignment value shall be a non-negative
>integral power of two." So asking operator new for any other value
>doesn't make sense, but I can't find a restriction on doing so.
>
>I was assuming we only need to ensure it's possible to use valid
>alignments such as align_val_t(2) which are not valid arguments to
>posix_memalign. For other values such as align_val_t(15) I was
>assuming it's OK for posix_memalign to fail, so we throw bad_alloc.
>
>If that's not the case then we need to round up all alignments that
>aren't power of two multiples of sizeof(void*). I'd like to avoid
>that.
>
>>>Would using __builtin_expect (sz == 0, false) make sense?  Surely it's
>>>rare to try to allocate zero bytes.
>>
>>https://gcc.gnu.org/ml/libstdc++/2014-03/msg00001.html
>>
>>gcc already guesses that a test like sz == 0 is usually false (not 
>>with as large a probability as if you use __builtin_expect, but 
>>enough that the generated code is unlikely to differ). But adding 
>>__builtin_expect cannot hurt...
>>
>>Is the division (by a non-constant denominator) really necessary?
>
>Probably not, but I've asked the committee for clarification what this
>function should do when called with an invalid alignment.
>
>>Since align has to be a power of 2, x % align should be the same as 
>>x & (align - 1), for instance.
>
>Thanks, if it's UB to call it with alignments that aren't a power of
>two then we can do that.

I've committed the patch now, to fix the failures for Solaris. I'll
revisit it when I get clarification from the committee about invalid
alignment arguments.


^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: RFA (libstdc++): PATCH to implement C++17 over-aligned new
  2016-09-16 13:13                                       ` Jonathan Wakely
@ 2016-09-16 13:17                                         ` Rainer Orth
  2016-09-16 18:19                                         ` Jonathan Wakely
  1 sibling, 0 replies; 42+ messages in thread
From: Rainer Orth @ 2016-09-16 13:17 UTC (permalink / raw)
  To: Jonathan Wakely
  Cc: libstdc++,
	Jason Merrill, Christophe Lyon, Andreas Schwab, gcc-patches List

Hi Jonathan,

> I've committed the patch now, to fix the failures for Solaris. I'll
> revisit it when I get clarification from the committee about invalid
> alignment arguments.

Solaris bootstraps with the revised patch included just completed
successfully.

Thanks.
        Rainer

-- 
-----------------------------------------------------------------------------
Rainer Orth, Center for Biotechnology, Bielefeld University

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: RFA (libstdc++): PATCH to implement C++17 over-aligned new
  2016-09-16 13:13                                       ` Jonathan Wakely
  2016-09-16 13:17                                         ` Rainer Orth
@ 2016-09-16 18:19                                         ` Jonathan Wakely
  1 sibling, 0 replies; 42+ messages in thread
From: Jonathan Wakely @ 2016-09-16 18:19 UTC (permalink / raw)
  To: libstdc++
  Cc: Rainer Orth, Jason Merrill, Christophe Lyon, Andreas Schwab,
	gcc-patches List

[-- Attachment #1: Type: text/plain, Size: 877 bytes --]

On 16/09/16 13:12 +0100, Jonathan Wakely wrote:
>On 16/09/16 11:56 +0100, Jonathan Wakely wrote:
>>On 16/09/16 11:37 +0200, Marc Glisse wrote:
>>>Is the division (by a non-constant denominator) really necessary?
>>
>>Probably not, but I've asked the committee for clarification what this
>>function should do when called with an invalid alignment.
>>
>>>Since align has to be a power of 2, x % align should be the same 
>>>as x & (align - 1), for instance.
>>
>>Thanks, if it's UB to call it with alignments that aren't a power of
>>two then we can do that.
>
>I've committed the patch now, to fix the failures for Solaris. I'll
>revisit it when I get clarification from the committee about invalid
>alignment arguments.

I missed 18.6.2/1 which is clear that we don't have to support invalid
alignments passed to operator new, so I'm committing this.

Tested x86_64-linux.




[-- Attachment #2: patch.txt --]
[-- Type: text/x-patch, Size: 932 bytes --]

commit 0a70fa595953ff1e6e46266d7f86bc6d7e3400a4
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Fri Sep 16 17:36:44 2016 +0100

    Replace modulus with mask operation in over-aligned new
    
    2016-09-16  Jonathan Wakely  <jwakely@redhat.com>
    	    Marc Glisse  <marc.glisse@inria.fr>
    
    	* libsupc++/new_opa.cc [_GLIBCXX_HAVE_ALIGNED_ALLOC]
    	(operator new(size_t, align_val_t)): Replace modulus operator with
    	mask.

diff --git a/libstdc++-v3/libsupc++/new_opa.cc b/libstdc++-v3/libsupc++/new_opa.cc
index 9c859c1..91e53a8 100644
--- a/libstdc++-v3/libsupc++/new_opa.cc
+++ b/libstdc++-v3/libsupc++/new_opa.cc
@@ -69,7 +69,7 @@ operator new (std::size_t sz, std::align_val_t al)
 
 #if _GLIBCXX_HAVE_ALIGNED_ALLOC
   /* C11: the value of size shall be an integral multiple of alignment.  */
-  if (std::size_t rem = sz % align)
+  if (std::size_t rem = sz & (align - 1))
     sz += align - rem;
 #endif
 

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: RFA (libstdc++): PATCH to implement C++17 over-aligned new
  2016-09-08  7:10 RFA (libstdc++): PATCH to implement C++17 over-aligned new Jason Merrill
  2016-09-08  8:32 ` Marc Glisse
  2016-09-08 11:00 ` Jonathan Wakely
@ 2017-11-24 14:26 ` Marc Glisse
  2017-11-29 21:23   ` Jason Merrill
  2 siblings, 1 reply; 42+ messages in thread
From: Marc Glisse @ 2017-11-24 14:26 UTC (permalink / raw)
  To: Jason Merrill; +Cc: gcc-patches List

Hello,

@@ -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.  */
+    }
+

Code further in the function expects to be able to adjust args, which is 
defeated by copying them in align_args, see PR 82760.

-- 
Marc Glisse

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: RFA (libstdc++): PATCH to implement C++17 over-aligned new
  2017-11-24 14:26 ` Marc Glisse
@ 2017-11-29 21:23   ` Jason Merrill
  0 siblings, 0 replies; 42+ messages in thread
From: Jason Merrill @ 2017-11-29 21:23 UTC (permalink / raw)
  To: Marc Glisse; +Cc: gcc-patches List

On Fri, Nov 24, 2017 at 8:31 AM, Marc Glisse <marc.glisse@inria.fr> wrote:
> Hello,
>
> @@ -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.  */
> +    }
> +
>
> Code further in the function expects to be able to adjust args, which is
> defeated by copying them in align_args, see PR 82760.

Fixed, thanks.

^ permalink raw reply	[flat|nested] 42+ messages in thread

end of thread, other threads:[~2017-11-29 21:03 UTC | newest]

Thread overview: 42+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-09-08  7:10 RFA (libstdc++): PATCH to implement C++17 over-aligned new Jason Merrill
2016-09-08  8:32 ` Marc Glisse
2016-09-08 11:18   ` Jonathan Wakely
2016-09-09 21:40     ` Jason Merrill
2016-09-10  7:03       ` Christophe Lyon
2016-09-10 10:14         ` Marc Glisse
2016-09-10 10:35           ` Jonathan Wakely
2016-09-11  9:14         ` Christophe Lyon
2016-09-11  9:55           ` Jonathan Wakely
2016-09-11  9:56             ` Jonathan Wakely
2016-09-11 10:20             ` Christophe Lyon
2016-09-11 12:09               ` Jonathan Wakely
2016-09-13 13:04         ` Szabolcs Nagy
2016-09-10 10:14       ` Jonathan Wakely
2016-09-11  7:09       ` Andreas Schwab
2016-09-12 21:13         ` Jason Merrill
2016-09-13  8:41           ` Christophe Lyon
2016-09-13 12:37           ` Andreas Schwab
2016-09-13 12:54             ` Jason Merrill
2016-09-13 13:18               ` Andreas Schwab
2016-09-13 13:21                 ` Jason Merrill
2016-09-14 12:13                   ` Andreas Schwab
2016-09-14 16:11                     ` Christophe Lyon
2016-09-14 16:37                       ` Jason Merrill
2016-09-15 10:00                         ` Rainer Orth
2016-09-15 12:23                           ` Christophe Lyon
2016-09-15 20:09                             ` Jason Merrill
2016-09-16  7:12                               ` Rainer Orth
2016-09-16  8:15                                 ` Christophe Lyon
2016-09-16  9:14                                 ` Jonathan Wakely
2016-09-16  9:51                                   ` Marc Glisse
2016-09-16 11:12                                     ` Jonathan Wakely
2016-09-16 13:13                                       ` Jonathan Wakely
2016-09-16 13:17                                         ` Rainer Orth
2016-09-16 18:19                                         ` Jonathan Wakely
2016-09-12 14:15       ` Rainer Orth
2016-09-12 16:19         ` Jonathan Wakely
2016-09-12 18:57           ` Jason Merrill
2016-09-14 12:11           ` Rainer Orth
2016-09-08 11:00 ` Jonathan Wakely
2017-11-24 14:26 ` Marc Glisse
2017-11-29 21:23   ` Jason Merrill

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).