+2014-12-15 Jason Merrill <jason@redhat.com>
+
+ * c.opt (-fsized-deallocation, -Wc++14-compat): New.
+ (-Wsized-deallocation): New.
+ * c-opts.c (c_common_post_options): -fsized-deallocation defaults
+ to on in C++14 and up.
+
2014-12-11 Jason Merrill <jason@redhat.com>
* c-cppbuiltin.c (c_cpp_builtins): Enable C++14 __cpp_constexpr.
else if (warn_narrowing == -1)
warn_narrowing = 0;
+ /* Global sized deallocation is new in C++14. */
+ if (flag_sized_deallocation == -1)
+ flag_sized_deallocation = (cxx_dialect >= cxx14);
+
if (flag_extern_tls_init)
{
#if !defined (ASM_OUTPUT_DEF) || !SUPPORTS_WEAK
C++ ObjC++ Warning Alias(Wc++0x-compat)
Warn about C++ constructs whose meaning differs between ISO C++ 1998 and ISO C++ 2011
+Wc++14-compat
+C++ ObjC++ Var(warn_cxx14_compat) Warning LangEnabledBy(C++ ObjC++,Wall)
+Warn about C++ constructs whose meaning differs between ISO C++ 2011 and ISO C++ 2014
+
Wcast-qual
C ObjC C++ ObjC++ Var(warn_cast_qual) Warning
Warn about casts which discard qualifiers
C ObjC C++ ObjC++ Var(warn_missing_field_initializers) Warning EnabledBy(Wextra)
Warn about missing fields in struct initializers
+Wsized-deallocation
+C++ ObjC++ Var(warn_sized_deallocation) Warning EnabledBy(Wextra)
+Warn about missing sized deallocation functions
+
Wsizeof-pointer-memaccess
C ObjC C++ ObjC++ Var(warn_sizeof_pointer_memaccess) Warning LangEnabledBy(C ObjC C++ ObjC++,Wall)
Warn about suspicious length parameters to certain string functions if the argument uses sizeof
C ObjC C++ ObjC++ LTO Var(flag_signed_char)
Make \"char\" signed by default
+fsized-deallocation
+C++ ObjC++ Var(flag_sized_deallocation) Init(-1)
+Enable C++14 sized deallocation support
+
fsquangle
C++ ObjC++ Ignore Warn(switch %qs is no longer supported)
+2014-12-15 Jason Merrill <jason@redhat.com>
+
+ N3778: Sized Deallocation
+ * call.c (non_placement_deallocation_fn_p): A global sized
+ operator delete is not a usual deallocation function until C++14.
+ (build_op_delete_call): Choose the global sized op delete if we
+ know the size.
+ * cp-tree.h: Declare non_placement_deallocation_fn_p.
+ (enum cp_tree_index): Remove CPTI_GLOBAL_DELETE_FNDECL.
+ (global_delete_fndecl): Remove.
+ * decl.c (cxx_init_decl_processing): Also declare sized op deletes.
+ (grok_op_properties): Warn about sized dealloc without the flag.
+ * init.c (build_builtin_delete_call): Remove.
+ (build_vec_delete_1, build_delete): Don't call it.
+ * decl2.c (maybe_warn_sized_delete): New.
+ (cp_write_global_declarations): Call it.
+
2014-12-15 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/58882
/* Returns true iff T, an element of an OVERLOAD chain, is a usual
deallocation function (3.7.4.2 [basic.stc.dynamic.deallocation]). */
-static bool
+bool
non_placement_deallocation_fn_p (tree t)
{
/* A template instance is never a usual deallocation function,
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. */
+ bool global = DECL_NAMESPACE_SCOPE_P (t);
t = FUNCTION_ARG_CHAIN (t);
if (t == void_list_node
|| (t && same_type_p (TREE_VALUE (t), size_type_node)
+ && (!global || flag_sized_deallocation)
&& TREE_CHAIN (t) == void_list_node))
return true;
return false;
which has type std::size_t (18.2), then this function is a
usual deallocation function."
- So (void*) beats (void*, size_t). */
- if (FUNCTION_ARG_CHAIN (fn) == void_list_node)
- break;
+ So in a class (void*) beats (void*, size_t). */
+ 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:
+
+ If deallocation function lookup finds both a usual
+ deallocation function with only a pointer parameter and a
+ usual deallocation function with both a pointer parameter
+ and a size parameter, the function to be called is selected
+ as follows:
+
+ * If the type is complete and if, for the second alternative
+ (delete array) only, the operand is a pointer to a class
+ type with a non-trivial destructor or a (possibly
+ multi-dimensional) array thereof, the function with two
+ parameters is selected.
+
+ * Otherwise, it is unspecified which of the two deallocation
+ functions is selected. */
+ else
+ {
+ bool 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;
+ }
}
}
CPTI_CONST_TYPE_INFO_TYPE,
CPTI_TYPE_INFO_PTR_TYPE,
CPTI_ABORT_FNDECL,
- CPTI_GLOBAL_DELETE_FNDECL,
CPTI_AGGR_TAG,
CPTI_CTOR_IDENTIFIER,
#define const_type_info_type_node cp_global_trees[CPTI_CONST_TYPE_INFO_TYPE]
#define type_info_ptr_type cp_global_trees[CPTI_TYPE_INFO_PTR_TYPE]
#define abort_fndecl cp_global_trees[CPTI_ABORT_FNDECL]
-#define global_delete_fndecl cp_global_trees[CPTI_GLOBAL_DELETE_FNDECL]
#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]
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 tree build_op_delete_call (enum tree_code, tree, tree,
bool, tree, tree,
tsubst_flags_t);
tree abort_fndecl;
- The FUNCTION_DECL for the default `::operator delete'.
-
- tree global_delete_fndecl;
-
Used by RTTI
tree type_info_type_node, tinfo_decl_id, tinfo_decl_type;
tree tinfo_var_id; */
opnew = push_cp_library_fn (VEC_NEW_EXPR, newtype, 0);
DECL_IS_MALLOC (opnew) = 1;
DECL_IS_OPERATOR_NEW (opnew) = 1;
- global_delete_fndecl = push_cp_library_fn (DELETE_EXPR, deltype, ECF_NOTHROW);
+ push_cp_library_fn (DELETE_EXPR, deltype, ECF_NOTHROW);
push_cp_library_fn (VEC_DELETE_EXPR, deltype, ECF_NOTHROW);
+ if (flag_sized_deallocation)
+ {
+ /* Also push the sized deallocation variants:
+ void operator delete(void*, std::size_t) throw();
+ void operator delete[](void*, std::size_t) throw(); */
+ tree void_ftype_ptr_size
+ = build_function_type_list (void_type_node, ptr_type_node,
+ size_type_node, NULL_TREE);
+ deltype = cp_build_type_attribute_variant (void_ftype_ptr_size,
+ 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));
error ("%qD may not be declared as static", decl);
return false;
}
+ if (!flag_sized_deallocation && warn_cxx14_compat)
+ {
+ tree parm = FUNCTION_ARG_CHAIN (decl);
+ if (parm && same_type_p (TREE_VALUE (parm), size_type_node)
+ && TREE_CHAIN (parm) == void_list_node)
+ warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wc__14_compat,
+ "%qD is a usual (non-placement) deallocation "
+ "function in C++14 (or with -fsized-deallocation)",
+ decl);
+ }
}
}
}
}
+/* Check the deallocation functions for CODE to see if we want to warn that
+ only one was defined. */
+
+static void
+maybe_warn_sized_delete (enum tree_code code)
+{
+ tree sized = NULL_TREE;
+ tree unsized = NULL_TREE;
+
+ for (tree ovl = IDENTIFIER_GLOBAL_VALUE (ansi_opname (code));
+ ovl; ovl = OVL_NEXT (ovl))
+ {
+ tree fn = OVL_CURRENT (ovl);
+ /* We're only interested in usual deallocation functions. */
+ if (!non_placement_deallocation_fn_p (fn))
+ continue;
+ if (FUNCTION_ARG_CHAIN (fn) == void_list_node)
+ unsized = fn;
+ else
+ sized = fn;
+ }
+ if (DECL_INITIAL (unsized) && !DECL_INITIAL (sized))
+ warning_at (DECL_SOURCE_LOCATION (unsized), OPT_Wsized_deallocation,
+ "the program should also define %qD", sized);
+ else if (!DECL_INITIAL (unsized) && DECL_INITIAL (sized))
+ warning_at (DECL_SOURCE_LOCATION (sized), OPT_Wsized_deallocation,
+ "the program should also define %qD", unsized);
+}
+
+/* Check the global deallocation functions to see if we want to warn about
+ defining unsized without sized (or vice versa). */
+
+static void
+maybe_warn_sized_delete ()
+{
+ if (!flag_sized_deallocation || !warn_sized_deallocation)
+ return;
+ maybe_warn_sized_delete (DELETE_EXPR);
+ maybe_warn_sized_delete (VEC_DELETE_EXPR);
+}
+
/* This routine is called at the end of compilation.
Its job is to create all the code needed to initialize and
destroy the global aggregates. We do the destruction
FOR_EACH_VEC_SAFE_ELT (no_linkage_decls, i, decl)
no_linkage_error (decl);
+ maybe_warn_sized_delete ();
+
/* Then, do the Objective-C stuff. This is where all the
Objective-C module stuff gets generated (symtab,
class/protocol/selector lists etc). This must be done after C++
static void expand_aggr_init_1 (tree, tree, tree, tree, int, tsubst_flags_t);
static void expand_default_init (tree, tree, tree, tree, int, tsubst_flags_t);
static void perform_member_init (tree, tree);
-static tree build_builtin_delete_call (tree);
static int member_init_ok_or_else (tree, tree, tree);
static void expand_virtual_init (tree, tree);
static tree sort_mem_initializers (tree, tree);
}
\f
/* Common subroutines of build_new and build_vec_delete. */
-
-/* Call the global __builtin_delete to delete ADDR. */
-
-static tree
-build_builtin_delete_call (tree addr)
-{
- mark_used (global_delete_fndecl);
- return build_call_n (global_delete_fndecl, 1, addr);
-}
\f
/* Build and return a NEW_EXPR. If NELTS is non-NULL, TYPE[NELTS] is
the type of the object being allocated; otherwise, it's just TYPE.
"class-specific operator delete [] will be called, "
"even if they are declared when the class is defined");
}
- return build_builtin_delete_call (base);
+ /* This size won't actually be used. */
+ size_exp = size_one_node;
+ goto no_destructor;
}
size_exp = size_in_bytes (type);
if (TYPE_PTR_P (otype))
{
- bool complete_p = true;
-
addr = mark_rvalue_use (addr);
/* We don't want to warn about delete of void*, only other
"operator delete will be called, even if they are "
"declared when the class is defined");
}
- complete_p = false;
}
else if (auto_delete == sfk_deleting_destructor && warn_delnonvdtor
&& MAYBE_CLASS_TYPE_P (type) && !CLASSTYPE_FINAL (type)
}
}
}
- if (VOID_TYPE_P (type) || !complete_p || !MAYBE_CLASS_TYPE_P (type))
- /* Call the builtin operator delete. */
- return build_builtin_delete_call (addr);
if (TREE_SIDE_EFFECTS (addr))
addr = save_expr (addr);
addr = save_expr (addr);
head = get_target_expr (build_headof (addr));
/* Delete the object. */
- do_delete = build_builtin_delete_call (head);
+ do_delete = build_op_delete_call (DELETE_EXPR,
+ head,
+ cxx_sizeof_nowarn (type),
+ /*global_p=*/true,
+ /*placement=*/NULL_TREE,
+ /*alloc_fn=*/NULL_TREE,
+ complain);
/* Otherwise, treat this like a complete object destructor
call. */
auto_delete = sfk_complete_destructor;
-fno-nonansi-builtins -fnothrow-opt -fno-operator-names @gol
-fno-optional-diags -fpermissive @gol
-fno-pretty-templates @gol
--frepo -fno-rtti -fstats -ftemplate-backtrace-limit=@var{n} @gol
+-frepo -fno-rtti -fsized-deallocation @gol
+-fstats -ftemplate-backtrace-limit=@var{n} @gol
-ftemplate-depth=@var{n} @gol
-fno-threadsafe-statics -fuse-cxa-atexit @gol
-fno-weak -nostdinc++ @gol
-Wbool-compare @gol
-Wno-attributes -Wno-builtin-macro-redefined @gol
-Wc90-c99-compat -Wc99-c11-compat @gol
--Wc++-compat -Wc++11-compat -Wcast-align -Wcast-qual @gol
+-Wc++-compat -Wc++11-compat -Wc++14-compat -Wcast-align -Wcast-qual @gol
-Wchar-subscripts -Wclobbered -Wcomment -Wconditionally-supported @gol
-Wconversion -Wcoverage-mismatch -Wdate-time -Wdelete-incomplete -Wno-cpp @gol
-Wno-deprecated -Wno-deprecated-declarations -Wno-designated-init @gol
do not require run-time type information, i.e.@: casts to @code{void *} or to
unambiguous base classes.
+@item -fsized-deallocation
+@opindex fsized-deallocation
+Enable the built-in global declarations
+@smallexample
+void operator delete (void *, std::size_t) noexcept;
+void operator delete[] (void *, std::size_t) noexcept;
+@end smallexample
+as introduced in C++14. This is useful for user-defined replacement
+deallocation functions that, for example, use the size of the object
+to make deallocation faster. Enabled by default under
+@samp{-std=c++14} and above. The flag @option{-Wsized-deallocation} will
+warn about places that might want to add a definition.
+
@item -fstats
@opindex fstats
Emit statistics about front-end processing at the end of the compilation.
@gccoptlist{-Waddress @gol
-Warray-bounds @r{(only with} @option{-O2}@r{)} @gol
--Wc++11-compat @gol
+-Wc++11-compat -Wc++14-compat@gol
-Wchar-subscripts @gol
-Wenum-compare @r{(in C/ObjC; this is on by default in C++)} @gol
-Wimplicit-int @r{(C and Objective-C only)} @gol
in ISO C++ 2011. This warning turns on @option{-Wnarrowing} and is
enabled by @option{-Wall}.
+@item -Wc++14-compat @r{(C++ and Objective-C++ only)}
+Warn about C++ constructs whose meaning differs between ISO C++ 2011
+and ISO C++ 2014. This warning is enabled by @option{-Wall}.
+
@item -Wcast-qual
@opindex Wcast-qual
@opindex Wno-cast-qual
real to lower precision real values. This option is also enabled by
@option{-Wconversion}.
+@item -Wsized-deallocation @r{(C++ and Objective-C++ only)}
+@opindex Wsized-deallocation
+@opindex -Wno-sized-deallocation
+Warn about a definition of an unsized deallocation function
+@smallexample
+void operator delete (void *) noexcept;
+void operator delete[] (void *) noexcept;
+@end smallexample
+without a definition of the corresponding sized deallocation function
+@smallexample
+void operator delete (void *, std::size_t) noexcept;
+void operator delete[] (void *, std::size_t) noexcept;
+@end smallexample
+or vice versa. Enabled by @option{-Wextra} along with
+@option{-fsized-deallocation}.
+
@item -Wsizeof-pointer-memaccess
@opindex Wsizeof-pointer-memaccess
@opindex Wno-sizeof-pointer-memaccess
--- /dev/null
+// Test for C++14 sized deallocation. The operators delete defined below
+// should be called only in C++14 mode and above.
+// { dg-do run }
+
+extern "C" void abort();
+typedef __SIZE_TYPE__ size_t;
+#include <new>
+
+bool called;
+void operator delete[] (void *p, size_t s) throw()
+{
+ called = true;
+ operator delete[] (p);
+}
+
+void operator delete (void *p, size_t s) throw()
+{
+ called = true;
+ operator delete (p);
+}
+
+void operator delete[] (void *p, size_t s, const std::nothrow_t &) throw()
+{
+ called = true;
+ operator delete[] (p);
+}
+
+void operator delete (void *p, size_t s, const std::nothrow_t &) throw()
+{
+ called = true;
+ operator delete (p);
+}
+
+struct A { ~A(){} };
+
+struct B { };
+
+struct C;
+
+struct D { ~D(){}; D() { throw 1; } };
+
+int main()
+{
+ /* * 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. */
+ delete new int;
+ if (called != (__cplusplus >= 201402L)) abort(); called = false;
+
+ delete new A;
+ if (called != (__cplusplus >= 201402L)) abort(); called = false;
+
+ delete[] new A[2];
+ if (called != (__cplusplus >= 201402L)) abort(); called = false;
+
+ delete new B;
+ if (called != (__cplusplus >= 201402L)) abort(); called = false;
+
+ /* N3778 added the sized placement deallocation functions, but the core
+ language rules don't provide any way they would be called. */
+ try { new (std::nothrow) D; } catch (int) {}
+ if (called) abort();
+
+ try { new (std::nothrow) D[2]; } catch (int) {}
+ if (called) abort();
+
+ /* Make sure we don't try to use the size of an array that doesn't have a
+ cookie. */
+ delete[] new B[2];
+ if (called) abort();
+}
--- /dev/null
+// Test that -Wc++14-compat warns about the change in meaning.
+// { dg-options "-Wall" }
+
+typedef __SIZE_TYPE__ size_t;
+void operator delete[] (void *p, size_t s) throw(); // { dg-warning "usual" "" { target { ! c++14 } } }
--- /dev/null
+// { dg-options "-Wsized-deallocation" }
+
+void operator delete (void *p) throw() { __builtin_free(p); } // { dg-warning "sized" "" { target c++14 } }
inline void* operator new(__SIZE_TYPE__ n){ return __builtin_malloc(n); }
inline void operator delete(void *p) { __builtin_free(p); }
+// C++14 sized deallocation function
+inline void operator delete(void *p, __SIZE_TYPE__) { __builtin_free(p); }
struct O {
double num;
int count;
+2014-12-15 Jason Merrill <jason@redhat.com>
+
+ * libsupc++/del_ops.cc: New.
+ * libsupc++/del_opvs.cc: New.
+ * libsupc++/Makefile.am: Add them.
+ * libsupc++/Makefile.in: Regenerate.
+ * config/abi/pre/gnu.ver: Export _ZdlPvm and _ZdaPvm.
+
2014-12-13 Tim Shen <timshen@google.com>
PR libstdc++/64239
_ZTSP[no];
_ZTSPK[no];
+ # operator delete(void*, std::size_t)
+ _ZdlPvm;
+ # operator delete[](void*, std::size_t)
+ _ZdaPvm;
+
} CXXABI_1.3.8;
# Symbols in the support library (libsupc++) supporting transactional memory.
bad_typeid.cc \
class_type_info.cc \
del_op.cc \
+ del_ops.cc \
del_opnt.cc \
del_opv.cc \
+ del_opvs.cc \
del_opvnt.cc \
dyncast.cc \
eh_alloc.cc \
libsupc___la_LIBADD =
am__objects_1 = array_type_info.lo atexit_arm.lo atexit_thread.lo \
bad_alloc.lo bad_array_length.lo bad_array_new.lo bad_cast.lo \
- bad_typeid.lo class_type_info.lo del_op.lo del_opnt.lo \
- del_opv.lo del_opvnt.lo dyncast.lo eh_alloc.lo eh_arm.lo \
- eh_aux_runtime.lo eh_call.lo eh_catch.lo eh_exception.lo \
- eh_globals.lo eh_personality.lo eh_ptr.lo eh_term_handler.lo \
- eh_terminate.lo eh_tm.lo eh_throw.lo eh_type.lo \
- eh_unex_handler.lo enum_type_info.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
+ bad_typeid.lo class_type_info.lo del_op.lo del_ops.lo \
+ del_opnt.lo del_opv.lo del_opvs.lo del_opvnt.lo dyncast.lo \
+ eh_alloc.lo eh_arm.lo eh_aux_runtime.lo eh_call.lo eh_catch.lo \
+ eh_exception.lo eh_globals.lo eh_personality.lo eh_ptr.lo \
+ eh_term_handler.lo eh_terminate.lo eh_tm.lo eh_throw.lo \
+ eh_type.lo eh_unex_handler.lo enum_type_info.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
@GLIBCXX_HOSTED_TRUE@am__objects_2 = cp-demangle.lo
@ENABLE_VTABLE_VERIFY_TRUE@am__objects_3 = vtv_stubs.lo
am_libsupc___la_OBJECTS = $(am__objects_1) $(am__objects_2) \
bad_typeid.cc \
class_type_info.cc \
del_op.cc \
+ del_ops.cc \
del_opnt.cc \
del_opv.cc \
+ del_opvs.cc \
del_opvnt.cc \
dyncast.cc \
eh_alloc.cc \
--- /dev/null
+// Boilerplate support routines for -*- C++ -*- dynamic memory management.
+
+// Copyright (C) 1997-2014 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) _GLIBCXX_USE_NOEXCEPT
+{
+ ::operator delete (ptr);
+}
--- /dev/null
+// Boilerplate support routines for -*- C++ -*- dynamic memory management.
+
+// Copyright (C) 1997-2014 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) _GLIBCXX_USE_NOEXCEPT
+{
+ ::operator delete[] (ptr);
+}