mirror of git://gcc.gnu.org/git/gcc.git
N3639 C++1y VLA support
gcc/ * gimplify.c (gimplify_vla_decl): Don't touch an existing DECL_VALUE_EXPR. gcc/cp/ * decl.c (compute_array_index_type): Allow VLAs in C++1y mode. (check_array_initializer): Allow VLA init. (reshape_init_array_1): Adjust. (cp_finish_decl): Check for invalid VLA length. * typeck2.c (process_init_constructor_array): Adjust. (store_init_value): Use build_vec_init for VLAs. * semantics.c (add_capture): Capture VLA as ptr+len. (vla_capture_type): New. (build_capture_proxy): Rebuild the VLA. * typeck.c (build_simple_component_ref): Split out from... (build_ptrmemfunc_access_expr): ...here. * tree.c (array_of_runtime_bound_p): New. * init.c (throw_bad_array_length): New. (build_vec_init): Use it. * parser.c (cp_convert_range_for): When iterating over a VLA, use it directly rather than bind a reference. * cp-tree.h: Declare new functions. libstdc++-v3/ * libsupc++/new: Add std::bad_array_length. * libsupc++/bad_array_length.cc: New. * libsupc++/eh_aux_runtime.cc: Add __cxa_bad_array_length. * libsupc++/Makefile.in: Build them. * config/abi/pre/gnu.ver: Add new symbols. * config/abi/pre/gnu-versioned-namespace.ver: Add new symbols. From-SVN: r198745
This commit is contained in:
parent
a3409c0279
commit
0138d6b24f
|
|
@ -1,5 +1,9 @@
|
|||
2013-05-09 Jason Merrill <jason@redhat.com>
|
||||
|
||||
N3639 C++1y VLA support
|
||||
* gimplify.c (gimplify_vla_decl): Don't touch an existing
|
||||
DECL_VALUE_EXPR.
|
||||
|
||||
* tree.c (build_constructor_va): New.
|
||||
* tree.h: Declare it.
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,24 @@
|
|||
2013-05-09 Jason Merrill <jason@redhat.com>
|
||||
|
||||
N3639 C++1y VLA support
|
||||
* decl.c (compute_array_index_type): Allow VLAs in C++1y mode.
|
||||
(check_array_initializer): Allow VLA init.
|
||||
(reshape_init_array_1): Adjust.
|
||||
(cp_finish_decl): Check for invalid VLA length.
|
||||
* typeck2.c (process_init_constructor_array): Adjust.
|
||||
(store_init_value): Use build_vec_init for VLAs.
|
||||
* semantics.c (add_capture): Capture VLA as ptr+len.
|
||||
(vla_capture_type): New.
|
||||
(build_capture_proxy): Rebuild the VLA.
|
||||
* typeck.c (build_simple_component_ref): Split out from...
|
||||
(build_ptrmemfunc_access_expr): ...here.
|
||||
* tree.c (array_of_runtime_bound_p): New.
|
||||
* init.c (throw_bad_array_length): New.
|
||||
(build_vec_init): Use it.
|
||||
* parser.c (cp_convert_range_for): When iterating over a VLA,
|
||||
use it directly rather than bind a reference.
|
||||
* cp-tree.h: Declare new functions.
|
||||
|
||||
2013-05-08 Jason Merrill <jason@redhat.com>
|
||||
|
||||
* except.c (is_admissible_throw_operand_or_catch_parameter): Check
|
||||
|
|
|
|||
|
|
@ -5358,6 +5358,7 @@ extern tree build_value_init_noctor (tree, tsubst_flags_t);
|
|||
extern tree build_offset_ref (tree, tree, bool,
|
||||
tsubst_flags_t);
|
||||
extern tree throw_bad_array_new_length (void);
|
||||
extern tree throw_bad_array_length (void);
|
||||
extern tree build_new (vec<tree, va_gc> **, tree, tree,
|
||||
vec<tree, va_gc> **, int,
|
||||
tsubst_flags_t);
|
||||
|
|
@ -5849,6 +5850,7 @@ extern tree get_target_expr (tree);
|
|||
extern tree get_target_expr_sfinae (tree, tsubst_flags_t);
|
||||
extern tree build_cplus_array_type (tree, tree);
|
||||
extern tree build_array_of_n_type (tree, int);
|
||||
extern bool array_of_runtime_bound_p (tree);
|
||||
extern tree build_array_copy (tree);
|
||||
extern tree build_vec_init_expr (tree, tree, tsubst_flags_t);
|
||||
extern void diagnose_non_constexpr_vec_init (tree);
|
||||
|
|
@ -6032,6 +6034,7 @@ extern tree cp_build_binary_op (location_t,
|
|||
enum tree_code, tree, tree,
|
||||
tsubst_flags_t);
|
||||
#define cxx_sizeof(T) cxx_sizeof_or_alignof_type (T, SIZEOF_EXPR, true)
|
||||
extern tree build_simple_component_ref (tree, tree);
|
||||
extern tree build_ptrmemfunc_access_expr (tree, tree);
|
||||
extern tree build_address (tree);
|
||||
extern tree build_typed_address (tree, tree);
|
||||
|
|
|
|||
|
|
@ -5064,7 +5064,7 @@ reshape_init_array_1 (tree elt_type, tree max_index, reshape_iter *d,
|
|||
tsubst_flags_t complain)
|
||||
{
|
||||
tree new_init;
|
||||
bool sized_array_p = (max_index != NULL_TREE);
|
||||
bool sized_array_p = (max_index && TREE_CONSTANT (max_index));
|
||||
unsigned HOST_WIDE_INT max_index_cst = 0;
|
||||
unsigned HOST_WIDE_INT index;
|
||||
|
||||
|
|
@ -5514,15 +5514,12 @@ check_array_initializer (tree decl, tree type, tree init)
|
|||
error ("elements of array %q#T have incomplete type", type);
|
||||
return true;
|
||||
}
|
||||
/* It is not valid to initialize a VLA. */
|
||||
if (init
|
||||
/* A compound literal can't have variable size. */
|
||||
if (init && !decl
|
||||
&& ((COMPLETE_TYPE_P (type) && !TREE_CONSTANT (TYPE_SIZE (type)))
|
||||
|| !TREE_CONSTANT (TYPE_SIZE (element_type))))
|
||||
{
|
||||
if (decl)
|
||||
error ("variable-sized object %qD may not be initialized", decl);
|
||||
else
|
||||
error ("variable-sized compound literal");
|
||||
error ("variable-sized compound literal");
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
@ -6405,6 +6402,21 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
|
|||
&& TYPE_FOR_JAVA (type) && MAYBE_CLASS_TYPE_P (type))
|
||||
error ("non-static data member %qD has Java class type", decl);
|
||||
|
||||
if (array_of_runtime_bound_p (type))
|
||||
{
|
||||
/* If the VLA bound is larger than half the address space, or less
|
||||
than zero, throw std::bad_array_length. */
|
||||
tree max = convert (ssizetype, TYPE_MAX_VALUE (TYPE_DOMAIN (type)));
|
||||
/* C++1y says we should throw for length <= 0, but we have
|
||||
historically supported zero-length arrays. Let's treat that as an
|
||||
extension to be disabled by -std=c++NN. */
|
||||
int lower = flag_iso ? 0 : -1;
|
||||
tree comp = build2 (LT_EXPR, boolean_type_node, max, ssize_int (lower));
|
||||
comp = build3 (COND_EXPR, void_type_node, comp,
|
||||
throw_bad_array_length (), void_zero_node);
|
||||
finish_expr_stmt (comp);
|
||||
}
|
||||
|
||||
/* Add this declaration to the statement-tree. This needs to happen
|
||||
after the call to check_initializer so that the DECL_EXPR for a
|
||||
reference temp is added before the DECL_EXPR for the reference itself. */
|
||||
|
|
@ -8289,7 +8301,7 @@ compute_array_index_type (tree name, tree size, tsubst_flags_t complain)
|
|||
error ("size of array is not an integral constant-expression");
|
||||
size = integer_one_node;
|
||||
}
|
||||
else if (pedantic && warn_vla != 0)
|
||||
else if (cxx_dialect < cxx1y && pedantic && warn_vla != 0)
|
||||
{
|
||||
if (name)
|
||||
pedwarn (input_location, OPT_Wvla, "ISO C++ forbids variable length array %qD", name);
|
||||
|
|
|
|||
|
|
@ -2185,6 +2185,20 @@ throw_bad_array_new_length (void)
|
|||
return build_cxx_call (fn, 0, NULL, tf_warning_or_error);
|
||||
}
|
||||
|
||||
/* Call __cxa_bad_array_length to indicate that there were too many
|
||||
initializers. */
|
||||
|
||||
tree
|
||||
throw_bad_array_length (void)
|
||||
{
|
||||
tree fn = get_identifier ("__cxa_throw_bad_array_length");
|
||||
if (!get_global_value_if_present (fn, &fn))
|
||||
fn = push_throw_library_fn (fn, build_function_type_list (void_type_node,
|
||||
NULL_TREE));
|
||||
|
||||
return build_cxx_call (fn, 0, NULL, tf_warning_or_error);
|
||||
}
|
||||
|
||||
/* 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
|
||||
|
|
@ -3350,6 +3364,10 @@ build_vec_init (tree base, tree maxindex, tree init,
|
|||
store_constructor will handle the semantics for us. */
|
||||
|
||||
stmt_expr = build2 (INIT_EXPR, atype, base, init);
|
||||
if (length_check)
|
||||
stmt_expr = build3 (COND_EXPR, atype, length_check,
|
||||
throw_bad_array_length (),
|
||||
stmt_expr);
|
||||
return stmt_expr;
|
||||
}
|
||||
|
||||
|
|
@ -3467,6 +3485,9 @@ build_vec_init (tree base, tree maxindex, tree init,
|
|||
if (length_check)
|
||||
{
|
||||
tree throw_call;
|
||||
if (array_of_runtime_bound_p (atype))
|
||||
throw_call = throw_bad_array_length ();
|
||||
else
|
||||
throw_call = throw_bad_array_new_length ();
|
||||
length_check = build3 (COND_EXPR, void_type_node, length_check,
|
||||
throw_call, void_zero_node);
|
||||
|
|
|
|||
|
|
@ -9842,13 +9842,21 @@ cp_convert_range_for (tree statement, tree range_decl, tree range_expr)
|
|||
begin_expr = end_expr = iter_type = error_mark_node;
|
||||
else
|
||||
{
|
||||
tree range_temp = build_range_temp (range_expr);
|
||||
pushdecl (range_temp);
|
||||
cp_finish_decl (range_temp, range_expr,
|
||||
/*is_constant_init*/false, NULL_TREE,
|
||||
LOOKUP_ONLYCONVERTING);
|
||||
tree range_temp;
|
||||
|
||||
range_temp = convert_from_reference (range_temp);
|
||||
if (TREE_CODE (range_expr) == VAR_DECL
|
||||
&& array_of_runtime_bound_p (TREE_TYPE (range_expr)))
|
||||
/* Can't bind a reference to an array of runtime bound. */
|
||||
range_temp = range_expr;
|
||||
else
|
||||
{
|
||||
range_temp = build_range_temp (range_expr);
|
||||
pushdecl (range_temp);
|
||||
cp_finish_decl (range_temp, range_expr,
|
||||
/*is_constant_init*/false, NULL_TREE,
|
||||
LOOKUP_ONLYCONVERTING);
|
||||
range_temp = convert_from_reference (range_temp);
|
||||
}
|
||||
iter_type = cp_parser_perform_range_for_lookup (range_temp,
|
||||
&begin_expr, &end_expr);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9379,6 +9379,21 @@ build_capture_proxy (tree member)
|
|||
name = DECL_NAME (member);
|
||||
|
||||
type = lambda_proxy_type (object);
|
||||
|
||||
if (TREE_CODE (type) == RECORD_TYPE
|
||||
&& TYPE_NAME (type) == NULL_TREE)
|
||||
{
|
||||
/* Rebuild the VLA type from the pointer and maxindex. */
|
||||
tree field = next_initializable_field (TYPE_FIELDS (type));
|
||||
tree ptr = build_simple_component_ref (object, field);
|
||||
field = next_initializable_field (DECL_CHAIN (field));
|
||||
tree max = build_simple_component_ref (object, field);
|
||||
type = build_array_type (TREE_TYPE (TREE_TYPE (ptr)),
|
||||
build_index_type (max));
|
||||
object = convert (build_reference_type (type), ptr);
|
||||
object = convert_from_reference (object);
|
||||
}
|
||||
|
||||
var = build_decl (input_location, VAR_DECL, name, type);
|
||||
SET_DECL_VALUE_EXPR (var, object);
|
||||
DECL_HAS_VALUE_EXPR_P (var) = 1;
|
||||
|
|
@ -9400,6 +9415,28 @@ build_capture_proxy (tree member)
|
|||
return var;
|
||||
}
|
||||
|
||||
/* Return a struct containing a pointer and a length for lambda capture of
|
||||
an array of runtime length. */
|
||||
|
||||
static tree
|
||||
vla_capture_type (tree array_type)
|
||||
{
|
||||
static tree ptr_id, max_id;
|
||||
if (!ptr_id)
|
||||
{
|
||||
ptr_id = get_identifier ("ptr");
|
||||
max_id = get_identifier ("max");
|
||||
}
|
||||
tree ptrtype = build_pointer_type (TREE_TYPE (array_type));
|
||||
tree field1 = build_decl (input_location, FIELD_DECL, ptr_id, ptrtype);
|
||||
tree field2 = build_decl (input_location, FIELD_DECL, max_id, sizetype);
|
||||
DECL_CHAIN (field2) = field1;
|
||||
tree type = make_node (RECORD_TYPE);
|
||||
finish_builtin_struct (type, "__cap", field2, NULL_TREE);
|
||||
TYPE_NAME (type) = NULL_TREE;
|
||||
return type;
|
||||
}
|
||||
|
||||
/* From an ID and INITIALIZER, create a capture (by reference if
|
||||
BY_REFERENCE_P is true), add it to the capture-list for LAMBDA,
|
||||
and return it. */
|
||||
|
|
@ -9415,7 +9452,22 @@ add_capture (tree lambda, tree id, tree initializer, bool by_reference_p,
|
|||
initializer = build_x_compound_expr_from_list (initializer, ELK_INIT,
|
||||
tf_warning_or_error);
|
||||
type = lambda_capture_field_type (initializer, explicit_init_p);
|
||||
if (by_reference_p)
|
||||
if (array_of_runtime_bound_p (type))
|
||||
{
|
||||
/* For a VLA, we capture the address of the first element and the
|
||||
maximum index, and then reconstruct the VLA for the proxy. */
|
||||
gcc_assert (by_reference_p);
|
||||
tree elt = cp_build_array_ref (input_location, initializer,
|
||||
integer_zero_node, tf_warning_or_error);
|
||||
tree ctype = vla_capture_type (type);
|
||||
tree ptr_field = next_initializable_field (TYPE_FIELDS (ctype));
|
||||
tree nelts_field = next_initializable_field (DECL_CHAIN (ptr_field));
|
||||
initializer = build_constructor_va (ctype, 2,
|
||||
ptr_field, build_address (elt),
|
||||
nelts_field, array_type_nelts (type));
|
||||
type = ctype;
|
||||
}
|
||||
else if (by_reference_p)
|
||||
{
|
||||
type = build_reference_type (type);
|
||||
if (!real_lvalue_p (initializer))
|
||||
|
|
|
|||
|
|
@ -871,6 +871,21 @@ build_array_of_n_type (tree elt, int n)
|
|||
return build_cplus_array_type (elt, build_index_type (size_int (n - 1)));
|
||||
}
|
||||
|
||||
/* True iff T is a C++1y array of runtime bound (VLA). */
|
||||
|
||||
bool
|
||||
array_of_runtime_bound_p (tree t)
|
||||
{
|
||||
if (!t || TREE_CODE (t) != ARRAY_TYPE)
|
||||
return false;
|
||||
tree dom = TYPE_DOMAIN (t);
|
||||
if (!dom)
|
||||
return false;
|
||||
tree max = TYPE_MAX_VALUE (dom);
|
||||
return (!value_dependent_expression_p (max)
|
||||
&& !TREE_CONSTANT (max));
|
||||
}
|
||||
|
||||
/* Return a reference type node referring to TO_TYPE. If RVAL is
|
||||
true, return an rvalue reference type, otherwise return an lvalue
|
||||
reference type. If a type node exists, reuse it, otherwise create
|
||||
|
|
|
|||
|
|
@ -2788,6 +2788,19 @@ finish_class_member_access_expr (tree object, tree name, bool template_p,
|
|||
return expr;
|
||||
}
|
||||
|
||||
/* Build a COMPONENT_REF of OBJECT and MEMBER with the appropriate
|
||||
type. */
|
||||
|
||||
tree
|
||||
build_simple_component_ref (tree object, tree member)
|
||||
{
|
||||
tree type = cp_build_qualified_type (TREE_TYPE (member),
|
||||
cp_type_quals (TREE_TYPE (object)));
|
||||
return fold_build3_loc (input_location,
|
||||
COMPONENT_REF, type,
|
||||
object, member, NULL_TREE);
|
||||
}
|
||||
|
||||
/* Return an expression for the MEMBER_NAME field in the internal
|
||||
representation of PTRMEM, a pointer-to-member function. (Each
|
||||
pointer-to-member function type gets its own RECORD_TYPE so it is
|
||||
|
|
@ -2800,7 +2813,6 @@ build_ptrmemfunc_access_expr (tree ptrmem, tree member_name)
|
|||
{
|
||||
tree ptrmem_type;
|
||||
tree member;
|
||||
tree member_type;
|
||||
|
||||
/* This code is a stripped down version of
|
||||
build_class_member_access_expr. It does not work to use that
|
||||
|
|
@ -2810,11 +2822,7 @@ build_ptrmemfunc_access_expr (tree ptrmem, tree member_name)
|
|||
gcc_assert (TYPE_PTRMEMFUNC_P (ptrmem_type));
|
||||
member = lookup_member (ptrmem_type, member_name, /*protect=*/0,
|
||||
/*want_type=*/false, tf_warning_or_error);
|
||||
member_type = cp_build_qualified_type (TREE_TYPE (member),
|
||||
cp_type_quals (ptrmem_type));
|
||||
return fold_build3_loc (input_location,
|
||||
COMPONENT_REF, member_type,
|
||||
ptrmem, member, NULL_TREE);
|
||||
return build_simple_component_ref (ptrmem, member);
|
||||
}
|
||||
|
||||
/* Given an expression PTR for a pointer, return an expression
|
||||
|
|
|
|||
|
|
@ -795,10 +795,12 @@ store_init_value (tree decl, tree init, vec<tree, va_gc>** cleanups, int flags)
|
|||
will perform the dynamic initialization. */
|
||||
if (value != error_mark_node
|
||||
&& (TREE_SIDE_EFFECTS (value)
|
||||
|| array_of_runtime_bound_p (type)
|
||||
|| ! reduced_constant_expression_p (value)))
|
||||
{
|
||||
if (TREE_CODE (type) == ARRAY_TYPE
|
||||
&& TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (type)))
|
||||
&& (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (type))
|
||||
|| array_of_runtime_bound_p (type)))
|
||||
/* For an array, we only need/want a single cleanup region rather
|
||||
than one per element. */
|
||||
return build_vec_init (decl, NULL_TREE, value, false, 1,
|
||||
|
|
@ -1114,7 +1116,7 @@ process_init_constructor_array (tree type, tree init,
|
|||
if (TREE_CODE (type) == ARRAY_TYPE)
|
||||
{
|
||||
tree domain = TYPE_DOMAIN (type);
|
||||
if (domain)
|
||||
if (domain && TREE_CONSTANT (TYPE_MAX_VALUE (domain)))
|
||||
len = (tree_to_double_int (TYPE_MAX_VALUE (domain))
|
||||
- tree_to_double_int (TYPE_MIN_VALUE (domain))
|
||||
+ double_int_one)
|
||||
|
|
|
|||
|
|
@ -1382,6 +1382,10 @@ gimplify_vla_decl (tree decl, gimple_seq *seq_p)
|
|||
gimplify_one_sizepos (&DECL_SIZE (decl), seq_p);
|
||||
gimplify_one_sizepos (&DECL_SIZE_UNIT (decl), seq_p);
|
||||
|
||||
/* Don't mess with a DECL_VALUE_EXPR set by the front-end. */
|
||||
if (DECL_HAS_VALUE_EXPR_P (decl))
|
||||
return;
|
||||
|
||||
/* All occurrences of this decl in final gimplified code will be
|
||||
replaced by indirection. Setting DECL_VALUE_EXPR does two
|
||||
things: First, it lets the rest of the gimplifier know what
|
||||
|
|
|
|||
|
|
@ -0,0 +1,15 @@
|
|||
// N3639 allows initialization and capture of VLAs
|
||||
// { dg-options -std=c++1y }
|
||||
// { dg-do run }
|
||||
|
||||
void f(int n)
|
||||
{
|
||||
int ar[n] = { 42 };
|
||||
auto l = [&] { return ar[0]; };
|
||||
if (l() != 42) __builtin_abort ();
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
f(1);
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
// Test for throwing bad_array_length on invalid array length
|
||||
// { dg-options -std=c++1y }
|
||||
// { dg-do run }
|
||||
|
||||
#include <new>
|
||||
|
||||
int f(int i)
|
||||
{
|
||||
int ar[i]{1,2,3,4};
|
||||
return ar[i-1];
|
||||
}
|
||||
|
||||
void g(int i)
|
||||
{
|
||||
int ar[i];
|
||||
ar[0] = 42;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int ok = 0;
|
||||
f(4); // OK
|
||||
try { f(3); } // too small
|
||||
catch (std::bad_array_length) { ++ok; }
|
||||
try { g(-24); } // negative
|
||||
catch (std::bad_array_length) { ++ok; }
|
||||
|
||||
if (ok != 2)
|
||||
__builtin_abort ();
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
// Test for range-based for with VLAs.
|
||||
// { dg-options -std=c++1y }
|
||||
// { dg-do run }
|
||||
|
||||
#include <new>
|
||||
|
||||
void f(int i)
|
||||
{
|
||||
int ar[i];
|
||||
int j = 0;
|
||||
for (int& x : ar)
|
||||
x = ++j;
|
||||
[&ar]{
|
||||
int k = 0;
|
||||
for (int x : ar)
|
||||
if (x != ++k)
|
||||
__builtin_abort();
|
||||
}();
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
f(42); // OK
|
||||
}
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
// PR c++/29175
|
||||
// { dg-options "" }
|
||||
// { dg-options "-Wno-vla" }
|
||||
|
||||
void foo(int i)
|
||||
{
|
||||
int x[][i] = { 0 }; // { dg-error "variable-sized|storage size" }
|
||||
int x[][i] = { 0 };
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,13 @@
|
|||
2013-05-08 Jason Merrill <jason@redhat.com>
|
||||
|
||||
Add std::bad_array_length (N3639)
|
||||
* libsupc++/new: Add std::bad_array_length.
|
||||
* libsupc++/bad_array_length.cc: New.
|
||||
* libsupc++/eh_aux_runtime.cc: Add __cxa_bad_array_length.
|
||||
* libsupc++/Makefile.in: Build them.
|
||||
* config/abi/pre/gnu.ver: Add new symbols.
|
||||
* config/abi/pre/gnu-versioned-namespace.ver: Add new symbols.
|
||||
|
||||
2013-05-08 Andi Kleen <ak@linux.intel.com>
|
||||
|
||||
PR target/55947
|
||||
|
|
|
|||
|
|
@ -235,6 +235,9 @@ CXXABI_2.0 {
|
|||
__cxa_throw_bad_array_new_length;
|
||||
_Z*St20bad_array_new_length*;
|
||||
|
||||
__cxa_throw_bad_array_length;
|
||||
_Z*St16bad_array_length*;
|
||||
|
||||
# Default function.
|
||||
_ZSt11_Hash_bytesPKv*;
|
||||
|
||||
|
|
|
|||
|
|
@ -1559,6 +1559,9 @@ CXXABI_1.3.7 {
|
|||
CXXABI_1.3.8 {
|
||||
__cxa_throw_bad_array_new_length;
|
||||
_Z*St20bad_array_new_length*;
|
||||
|
||||
__cxa_throw_bad_array_length;
|
||||
_Z*St16bad_array_length*;
|
||||
} CXXABI_1.3.7;
|
||||
|
||||
# Symbols in the support library (libsupc++) supporting transactional memory.
|
||||
|
|
|
|||
|
|
@ -92,8 +92,8 @@ am__installdirs = "$(DESTDIR)$(toolexeclibdir)" "$(DESTDIR)$(bitsdir)" \
|
|||
LTLIBRARIES = $(noinst_LTLIBRARIES) $(toolexeclib_LTLIBRARIES)
|
||||
libsupc___la_LIBADD =
|
||||
am__objects_1 = array_type_info.lo atexit_arm.lo atexit_thread.lo \
|
||||
bad_alloc.lo bad_array_new.lo bad_cast.lo bad_typeid.lo \
|
||||
class_type_info.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 \
|
||||
|
|
@ -367,6 +367,7 @@ sources = \
|
|||
atexit_arm.cc \
|
||||
atexit_thread.cc \
|
||||
bad_alloc.cc \
|
||||
bad_array_length.cc \
|
||||
bad_array_new.cc \
|
||||
bad_cast.cc \
|
||||
bad_typeid.cc \
|
||||
|
|
@ -789,16 +790,22 @@ cp-demangle.lo: cp-demangle.c
|
|||
cp-demangle.o: cp-demangle.c
|
||||
$(C_COMPILE) -DIN_GLIBCPP_V3 -Wno-error -c $<
|
||||
|
||||
# Use special rules for the C++11 sources so that the proper flags are passed.
|
||||
# Use special rules for the C++11 and C++1y sources so that the proper
|
||||
# flags are passed.
|
||||
bad_array_length.lo: bad_array_length.cc
|
||||
$(LTCXXCOMPILE) -std=gnu++1y -c $<
|
||||
bad_array_length.o: bad_array_length.cc
|
||||
$(CXXCOMPILE) -std=gnu++1y -c $<
|
||||
|
||||
bad_array_new.lo: bad_array_new.cc
|
||||
$(LTCXXCOMPILE) -std=gnu++11 -c $<
|
||||
bad_array_new.o: bad_array_new.cc
|
||||
$(CXXCOMPILE) -std=gnu++11 -c $<
|
||||
|
||||
eh_aux_runtime.lo: eh_aux_runtime.cc
|
||||
$(LTCXXCOMPILE) -std=gnu++11 -c $<
|
||||
$(LTCXXCOMPILE) -std=gnu++1y -c $<
|
||||
eh_aux_runtime.o: eh_aux_runtime.cc
|
||||
$(CXXCOMPILE) -std=gnu++11 -c $<
|
||||
$(CXXCOMPILE) -std=gnu++1y -c $<
|
||||
|
||||
eh_ptr.lo: eh_ptr.cc
|
||||
$(LTCXXCOMPILE) -std=gnu++11 -c $<
|
||||
|
|
|
|||
|
|
@ -0,0 +1,36 @@
|
|||
// Copyright (C) 2013 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 <new>
|
||||
|
||||
namespace std {
|
||||
|
||||
bad_array_length::~bad_array_length() _GLIBCXX_USE_NOEXCEPT { }
|
||||
|
||||
const char*
|
||||
bad_array_length::what() const _GLIBCXX_USE_NOEXCEPT
|
||||
{
|
||||
return "std::bad_array_length";
|
||||
}
|
||||
|
||||
} // namespace std
|
||||
|
|
@ -154,6 +154,8 @@ namespace __cxxabiv1
|
|||
void
|
||||
__cxa_throw_bad_array_new_length() __attribute__((__noreturn__));
|
||||
|
||||
void
|
||||
__cxa_throw_bad_array_length() __attribute__((__noreturn__));
|
||||
|
||||
/**
|
||||
* @brief Demangling routine.
|
||||
|
|
|
|||
|
|
@ -40,3 +40,7 @@ __cxxabiv1::__cxa_bad_typeid ()
|
|||
extern "C" void
|
||||
__cxxabiv1::__cxa_throw_bad_array_new_length ()
|
||||
{ _GLIBCXX_THROW_OR_ABORT(std::bad_array_new_length()); }
|
||||
|
||||
extern "C" void
|
||||
__cxxabiv1::__cxa_throw_bad_array_length ()
|
||||
{ _GLIBCXX_THROW_OR_ABORT(std::bad_array_length()); }
|
||||
|
|
|
|||
|
|
@ -79,6 +79,23 @@ namespace std
|
|||
};
|
||||
#endif
|
||||
|
||||
// We throw this exception for GNU VLAs of negative length in all C++
|
||||
// dialects, so declare it if we aren't in strict conformance mode.
|
||||
#if __cplusplus > 201103L || !defined(__STRICT_ANSI__)
|
||||
class bad_array_length : public bad_alloc
|
||||
{
|
||||
public:
|
||||
bad_array_length() throw() { };
|
||||
|
||||
// This declaration is not useless:
|
||||
// http://gcc.gnu.org/onlinedocs/gcc-3.0.2/gcc_6.html#SEC118
|
||||
virtual ~bad_array_length() throw();
|
||||
|
||||
// See comment in eh_exception.cc.
|
||||
virtual const char* what() const throw();
|
||||
};
|
||||
#endif
|
||||
|
||||
struct nothrow_t { };
|
||||
|
||||
extern const nothrow_t nothrow;
|
||||
|
|
|
|||
Loading…
Reference in New Issue