static int spelling_length (void);
static char *print_spelling (char *);
static void warning_init (location_t, int, const char *);
-static tree digest_init (location_t, tree, tree, tree, bool, bool, bool, bool,
- bool, bool);
+static tree digest_init (location_t, tree, tree, tree, tree, bool, bool, bool,
+ bool, bool, bool);
static void output_init_element (location_t, tree, tree, bool, tree, tree, bool,
bool, struct obstack *);
static void output_pending_init_elements (int, struct obstack *);
t = build_constructor_single (type, field, t);
if (!maybe_const)
t = c_wrap_maybe_const (t, true);
- t = digest_init (loc, type, t,
+ t = digest_init (loc, field, type, t,
NULL_TREE, false, false, false, true, false, false);
TREE_CONSTANT (t) = TREE_CONSTANT (value);
return t;
}
bool constexpr_p = (VAR_P (decl)
&& C_DECL_DECLARED_CONSTEXPR (decl));
- value = digest_init (init_loc, type, init, origtype, npc, int_const_expr,
- arith_const_expr, true,
+ value = digest_init (init_loc, decl, type, init, origtype, npc,
+ int_const_expr, arith_const_expr, true,
TREE_STATIC (decl) || constexpr_p, constexpr_p);
/* Store the expression if valid; else report error. */
"type of object");
}
-/* Digest the parser output INIT as an initializer for type TYPE.
+/* Digest the parser output INIT as an initializer for type TYPE
+ initializing DECL.
Return a C expression of type TYPE to represent the initial value.
If ORIGTYPE is not NULL_TREE, it is the original type of INIT.
on initializers for 'constexpr' objects apply. */
static tree
-digest_init (location_t init_loc, tree type, tree init, tree origtype,
- bool null_pointer_constant, bool int_const_expr,
+digest_init (location_t init_loc, tree decl, tree type, tree init,
+ tree origtype, bool null_pointer_constant, bool int_const_expr,
bool arith_const_expr, bool strict_string,
bool require_constant, bool require_constexpr)
{
&& TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST)
{
unsigned HOST_WIDE_INT len = TREE_STRING_LENGTH (inside_init);
- unsigned unit = TYPE_PRECISION (typ1) / BITS_PER_UNIT;
-
- /* Subtract the size of a single (possibly wide) character
- because it's ok to ignore the terminating null char
- that is counted in the length of the constant. */
- if (compare_tree_int (TYPE_SIZE_UNIT (type), len - unit) < 0)
- pedwarn_init (init_loc, 0,
- ("initializer-string for array of %qT "
- "is too long"), typ1);
- else if (warn_unterminated_string_initialization
- && compare_tree_int (TYPE_SIZE_UNIT (type), len) < 0)
- warning_at (init_loc, OPT_Wunterminated_string_initialization,
- ("initializer-string for array of %qT "
- "is too long"), typ1);
+
if (compare_tree_int (TYPE_SIZE_UNIT (type), len) < 0)
{
- unsigned HOST_WIDE_INT size
+ unsigned HOST_WIDE_INT avail
= tree_to_uhwi (TYPE_SIZE_UNIT (type));
+ unsigned unit = TYPE_PRECISION (typ1) / BITS_PER_UNIT;
const char *p = TREE_STRING_POINTER (inside_init);
- inside_init = build_string (size, p);
+ /* Construct truncated string. */
+ inside_init = build_string (avail, p);
+
+ /* Subtract the size of a single (possibly wide) character
+ because it may be ok to ignore the terminating NUL char
+ that is counted in the length of the constant. */
+ if (len - unit > avail)
+ pedwarn_init (init_loc, 0,
+ "initializer-string for array of %qT "
+ "is too long (%wu chars into %wu "
+ "available)", typ1, len, avail);
+ else if (warn_cxx_compat)
+ warning_at (init_loc, OPT_Wc___compat,
+ "initializer-string for array of %qT "
+ "is too long for C++ (%wu chars into %wu "
+ "available)", typ1, len, avail);
+ else if (warn_unterminated_string_initialization
+ && get_attr_nonstring_decl (decl) == NULL_TREE)
+ warning_at (init_loc,
+ OPT_Wunterminated_string_initialization,
+ "initializer-string for array of %qT "
+ "truncates NUL terminator but destination "
+ "lacks %qs attribute (%wu chars into %wu "
+ "available)", typ1, "nonstring", len, avail);
}
}
if (!require_constexpr_value
|| !npc
|| TREE_CODE (constructor_type) != POINTER_TYPE)
- new_value = digest_init (loc, type, new_value, origtype, npc,
+ new_value = digest_init (loc, field, type, new_value, origtype, npc,
int_const_expr, arith_const_expr, strict_string,
require_constant_value, require_constexpr_value);
if (new_value == error_mark_node)