* c-common.c (braced_list_to_string): Remove eval parameter.
Add some more checks. Always create zero-terminated STRING_CST.
* c-common.h (braced_list_to_string): Adjust prototype.
* c-decl.c (finish_decl): Call braced_list_to_string here ...
* c-parser.c (c_parser_declaration_or_fndef): ... instead of here.
* decl.c (eval_check_narrowing): Remove.
(check_initializer): Move call to braced_list_to_string from here ...
* typeck2.c (store_init_value): ... to here.
(digest_init_r): Remove handing of signed/unsigned char strings.
* c-c++-common/array-init.c: New test.
* g++.dg/init/string2.C: Remove xfail.
From-SVN: r264042
+2018-09-02 Bernd Edlinger <bernd.edlinger@hotmail.de>
+
+ * c-common.c (braced_list_to_string): Remove eval parameter.
+ Add some more checks. Always create zero-terminated STRING_CST.
+ * c-common.h (braced_list_to_string): Adjust prototype.
+
2018-08-27 David Malcolm <dmalcolm@redhat.com>
PR 87091
}
/* Attempt to convert a braced array initializer list CTOR for array
- TYPE into a STRING_CST for convenience and efficiency. When non-null,
- use EVAL to attempt to evalue constants (used by C++). Return
- the converted string on success or null on failure. */
+ TYPE into a STRING_CST for convenience and efficiency. Return
+ the converted string on success or the original ctor on failure. */
tree
-braced_list_to_string (tree type, tree ctor, tree (*eval)(tree, tree))
+braced_list_to_string (tree type, tree ctor)
{
- unsigned HOST_WIDE_INT nelts = CONSTRUCTOR_NELTS (ctor);
+ if (!tree_fits_uhwi_p (TYPE_SIZE_UNIT (type)))
+ return ctor;
/* If the array has an explicit bound, use it to constrain the size
of the string. If it doesn't, be sure to create a string that's
as long as implied by the index of the last zero specified via
a designator, as in:
const char a[] = { [7] = 0 }; */
- unsigned HOST_WIDE_INT maxelts = HOST_WIDE_INT_M1U;
- if (tree size = TYPE_SIZE_UNIT (type))
- {
- if (tree_fits_uhwi_p (size))
- {
- maxelts = tree_to_uhwi (size);
- maxelts /= tree_to_uhwi (TYPE_SIZE_UNIT (TREE_TYPE (type)));
+ unsigned HOST_WIDE_INT maxelts = tree_to_uhwi (TYPE_SIZE_UNIT (type));
+ maxelts /= tree_to_uhwi (TYPE_SIZE_UNIT (TREE_TYPE (type)));
- /* Avoid converting initializers for zero-length arrays. */
- if (!maxelts)
- return NULL_TREE;
- }
- }
- else if (!nelts)
- /* Avoid handling the undefined/erroneous case of an empty
- initializer for an arrays with unspecified bound. */
- return NULL_TREE;
+ /* Avoid converting initializers for zero-length arrays. */
+ if (!maxelts)
+ return ctor;
- tree eltype = TREE_TYPE (type);
+ unsigned HOST_WIDE_INT nelts = CONSTRUCTOR_NELTS (ctor);
auto_vec<char> str;
str.reserve (nelts + 1);
FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (ctor), i, index, value)
{
- unsigned HOST_WIDE_INT idx = index ? tree_to_uhwi (index) : i;
+ unsigned HOST_WIDE_INT idx = i;
+ if (index)
+ {
+ if (!tree_fits_uhwi_p (index))
+ return ctor;
+ idx = tree_to_uhwi (index);
+ }
/* auto_vec is limited to UINT_MAX elements. */
if (idx > UINT_MAX)
- return NULL_TREE;
+ return ctor;
- /* Attempt to evaluate constants. */
- if (eval)
- value = eval (eltype, value);
-
- /* Avoid non-constant initializers. */
+ /* Avoid non-constant initializers. */
if (!tree_fits_shwi_p (value))
- return NULL_TREE;
+ return ctor;
/* Skip over embedded nuls except the last one (initializer
elements are in ascending order of indices). */
if (!val && i + 1 < nelts)
continue;
+ if (idx < str.length())
+ return ctor;
+
/* Bail if the CTOR has a block of more than 256 embedded nuls
due to implicitly initialized elements. */
unsigned nchars = (idx - str.length ()) + 1;
if (nchars > 256)
- return NULL_TREE;
+ return ctor;
if (nchars > 1)
{
str.quick_grow_cleared (idx);
}
- if (idx > maxelts)
- return NULL_TREE;
+ if (idx >= maxelts)
+ return ctor;
str.safe_insert (idx, val);
}
- if (!nelts)
- /* Append a nul for the empty initializer { }. */
+ /* Append a nul string termination. */
+ if (str.length () < maxelts)
str.safe_push (0);
- /* Build a STRING_CST with the same type as the array, which
- may be an array of unknown bound. */
+ /* Build a STRING_CST with the same type as the array. */
tree res = build_string (str.length (), str.begin ());
TREE_TYPE (res) = type;
return res;
extern void maybe_suggest_missing_token_insertion (rich_location *richloc,
enum cpp_ttype token_type,
location_t prev_token_loc);
-extern tree braced_list_to_string (tree, tree, tree (*)(tree, tree) = NULL);
+extern tree braced_list_to_string (tree, tree);
#if CHECKING_P
namespace selftest {
+2018-09-02 Bernd Edlinger <bernd.edlinger@hotmail.de>
+
+ * c-decl.c (finish_decl): Call braced_list_to_string here ...
+ * c-parser.c (c_parser_declaration_or_fndef): ... instead of here.
+
2018-08-30 Alexander Monakov <amonakov@ispras.ru>
* gimple-parser.c (c_parser_gimple_binary_expression): Accept infix
relayout_decl (decl);
}
+ if (TREE_CODE (type) == ARRAY_TYPE
+ && TYPE_STRING_FLAG (TREE_TYPE (type))
+ && DECL_INITIAL (decl)
+ && TREE_CODE (DECL_INITIAL (decl)) == CONSTRUCTOR)
+ DECL_INITIAL (decl) = braced_list_to_string (type, DECL_INITIAL (decl));
+
if (VAR_P (decl))
{
if (init && TREE_CODE (init) == CONSTRUCTOR)
if (d != error_mark_node)
{
maybe_warn_string_init (init_loc, TREE_TYPE (d), init);
-
- /* Try to convert a string CONSTRUCTOR into a STRING_CST. */
- tree valtype = TREE_TYPE (init.value);
- if (TREE_CODE (init.value) == CONSTRUCTOR
- && TREE_CODE (valtype) == ARRAY_TYPE
- && TYPE_STRING_FLAG (TREE_TYPE (valtype)))
- if (tree str = braced_list_to_string (valtype, init.value))
- init.value = str;
-
finish_decl (d, init_loc, init.value,
init.original_type, asm_name);
}
+2018-09-02 Bernd Edlinger <bernd.edlinger@hotmail.de>
+
+ * decl.c (eval_check_narrowing): Remove.
+ (check_initializer): Move call to braced_list_to_string from here ...
+ * typeck2.c (store_init_value): ... to here.
+ (digest_init_r): Remove handing of signed/unsigned char strings.
+
2018-08-31 Nathan Sidwell <nathan@acm.org>
PR c++/87155
return build_aggr_init (decl, init, flags, tf_warning_or_error);
}
-/* Attempt to determine the constant VALUE of integral type and convert
- it to TYPE, issuing narrowing warnings/errors as necessary. Return
- the constant result or null on failure. Callback for
- braced_list_to_string. */
-
-static tree
-eval_check_narrowing (tree type, tree value)
-{
- if (tree valtype = TREE_TYPE (value))
- {
- if (TREE_CODE (valtype) != INTEGER_TYPE)
- return NULL_TREE;
- }
- else
- return NULL_TREE;
-
- value = scalar_constant_value (value);
- if (!value)
- return NULL_TREE;
-
- check_narrowing (type, value, tf_warning_or_error);
- return value;
-}
-
/* Verify INIT (the initializer for DECL), and record the
initialization in DECL_INITIAL, if appropriate. CLEANUP is as for
grok_reference_init.
}
else
{
- /* Try to convert a string CONSTRUCTOR into a STRING_CST. */
- tree valtype = TREE_TYPE (decl);
- if (TREE_CODE (valtype) == ARRAY_TYPE
- && TYPE_STRING_FLAG (TREE_TYPE (valtype))
- && BRACE_ENCLOSED_INITIALIZER_P (init))
- if (tree str = braced_list_to_string (valtype, init,
- eval_check_narrowing))
- init = str;
-
- if (TREE_CODE (init) != STRING_CST)
- init = reshape_init (type, init, tf_warning_or_error);
+ init = reshape_init (type, init, tf_warning_or_error);
flags |= LOOKUP_NO_NARROWING;
}
}
/* Digest the specified initializer into an expression. */
value = digest_init_flags (type, init, flags, tf_warning_or_error);
+ if (TREE_CODE (type) == ARRAY_TYPE
+ && TYPE_STRING_FLAG (TREE_TYPE (type))
+ && TREE_CODE (value) == CONSTRUCTOR)
+ value = braced_list_to_string (type, value);
+
value = extend_ref_init_temps (decl, value, cleanups);
/* In C++11 constant expression is a semantic, not syntactic, property.
if (TYPE_PRECISION (typ1) == BITS_PER_UNIT)
{
- if (char_type != char_type_node
- && char_type != signed_char_type_node
- && char_type != unsigned_char_type_node)
+ if (char_type != char_type_node)
{
if (complain & tf_error)
error_at (loc, "char-array initialized from wide string");
+2018-09-02 Bernd Edlinger <bernd.edlinger@hotmail.de>
+
+ * c-c++-common/array-init.c: New test.
+ * g++.dg/init/string2.C: Remove selector.
+
2018-09-01 Michael Matz <matz@suse.de>
PR tree-optimization/87074
--- /dev/null
+/* { dg-do compile } */
+/* { dg-prune-output "sorry, unimplemented: non-trivial designated initializers not supported" } */
+
+char x[] = { [-1] = 1, 2, 3 }; /* { dg-error "array index in initializer exceeds array bounds" "" { target c } } */
int tmplen ()
{
static const T
- a[] = { 1, 2, 333, 0 }; // { dg-warning "\\\[\(-Wnarrowing|-Woverflow\)" "" { target { ! c++98_only } } }
+ a[] = { 1, 2, 333, 0 }; // { dg-warning "\\\[\(-Wnarrowing|-Woverflow\)" }
return __builtin_strlen (a);
}