return is_trivially_xible (MODIFY_EXPR, inner_elt_type, fromtype);
}
+/* Subroutine of build_vec_init: Check that the array has at least N
+ elements. Other parameters are local variables in build_vec_init. */
+
+void
+finish_length_check (tree atype, tree iterator, tree obase, unsigned n)
+{
+ tree nelts = build_int_cst (ptrdiff_type_node, n - 1);
+ if (TREE_CODE (atype) != ARRAY_TYPE)
+ {
+ if (flag_exceptions)
+ {
+ tree c = fold_build2 (LT_EXPR, boolean_type_node, iterator,
+ nelts);
+ c = build3 (COND_EXPR, void_type_node, c,
+ throw_bad_array_new_length (), void_node);
+ finish_expr_stmt (c);
+ }
+ /* Don't check an array new when -fno-exceptions. */
+ }
+ else if (flag_sanitize & SANITIZE_BOUNDS
+ && do_ubsan_in_current_function ())
+ {
+ /* Make sure the last element of the initializer is in bounds. */
+ finish_expr_stmt
+ (ubsan_instrument_bounds
+ (input_location, obase, &nelts, /*ignore_off_by_one*/false));
+ }
+}
+
/* `build_vec_init' returns tree structure that performs
initialization of a vector of aggregate types.
tree obase = base;
bool xvalue = false;
bool errors = false;
+ location_t loc = (init ? EXPR_LOC_OR_LOC (init, input_location)
+ : location_of (base));
if (TREE_CODE (atype) == ARRAY_TYPE && TYPE_DOMAIN (atype))
maxindex = array_type_nelts (atype);
}
}
- /* If we have a braced-init-list, make sure that the array
+ /* If we have a braced-init-list or string constant, make sure that the array
is big enough for all the initializers. */
- bool length_check = (init && TREE_CODE (init) == CONSTRUCTOR
- && CONSTRUCTOR_NELTS (init) > 0
+ bool length_check = (init
+ && (TREE_CODE (init) == STRING_CST
+ || (TREE_CODE (init) == CONSTRUCTOR
+ && CONSTRUCTOR_NELTS (init) > 0))
&& !TREE_CONSTANT (maxindex));
if (init
from_array = 0;
if (length_check)
- {
- tree nelts = build_int_cst (ptrdiff_type_node,
- CONSTRUCTOR_NELTS (init) - 1);
- if (TREE_CODE (atype) != ARRAY_TYPE)
- {
- if (flag_exceptions)
- {
- tree c = fold_build2 (LT_EXPR, boolean_type_node, iterator,
- nelts);
- c = build3 (COND_EXPR, void_type_node, c,
- throw_bad_array_new_length (), void_node);
- finish_expr_stmt (c);
- }
- /* Don't check an array new when -fno-exceptions. */
- }
- else if (flag_sanitize & SANITIZE_BOUNDS
- && do_ubsan_in_current_function ())
- {
- /* Make sure the last element of the initializer is in bounds. */
- finish_expr_stmt
- (ubsan_instrument_bounds
- (input_location, obase, &nelts, /*ignore_off_by_one*/false));
- }
- }
+ finish_length_check (atype, iterator, obase, CONSTRUCTOR_NELTS (init));
if (try_const)
vec_alloc (const_vec, CONSTRUCTOR_NELTS (init));
/* Any elements without explicit initializers get T{}. */
empty_list = true;
}
+ else if (init && TREE_CODE (init) == STRING_CST)
+ {
+ /* Check that the array is at least as long as the string. */
+ if (length_check)
+ finish_length_check (atype, iterator, obase,
+ TREE_STRING_LENGTH (init));
+ tree length = build_int_cst (ptrdiff_type_node,
+ TREE_STRING_LENGTH (init));
+
+ /* Copy the string to the first part of the array. */
+ tree alias_set = build_int_cst (build_pointer_type (type), 0);
+ tree lhs = build2 (MEM_REF, TREE_TYPE (init), base, alias_set);
+ tree stmt = build2 (MODIFY_EXPR, void_type_node, lhs, init);
+ finish_expr_stmt (stmt);
+
+ /* Adjust the counter and pointer. */
+ stmt = cp_build_binary_op (loc, MINUS_EXPR, iterator, length, complain);
+ stmt = build2 (MODIFY_EXPR, void_type_node, iterator, stmt);
+ finish_expr_stmt (stmt);
+
+ stmt = cp_build_binary_op (loc, PLUS_EXPR, base, length, complain);
+ stmt = build2 (MODIFY_EXPR, void_type_node, base, stmt);
+ finish_expr_stmt (stmt);
+
+ /* And set the rest of the array to NUL. */
+ from_array = 0;
+ explicit_value_init_p = true;
+ }
else if (from_array)
{
if (init)