backport: re PR c++/90947 (Simple lookup table of array of strings is miscompiled)
Backported from mainline 2019-10-31 Jakub Jelinek <jakub@redhat.com> PR c++/90947 * tree.h (type_initializer_zero_p): Remove. * tree.c (type_initializer_zero_p): Remove. * cp-tree.h (type_initializer_zero_p): Declare. * decl.c (reshape_init_array_1): Formatting fix. * tree.c (type_initializer_zero_p): New function. Moved from ../tree.c, use next_initializable_field, formatting fix. Return false for TYPE_NON_AGGREGATE_CLASS types. From-SVN: r277985
This commit is contained in:
parent
357a65e1ce
commit
8af68eba76
|
@ -1,6 +1,12 @@
|
|||
2019-11-08 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
Backported from mainline
|
||||
2019-10-31 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR c++/90947
|
||||
* tree.h (type_initializer_zero_p): Remove.
|
||||
* tree.c (type_initializer_zero_p): Remove.
|
||||
|
||||
2019-10-29 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* doc/install.texi (--enable-offload-targets): Fix up a typo in the
|
||||
|
|
|
@ -1,6 +1,15 @@
|
|||
2019-11-08 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
Backported from mainline
|
||||
2019-10-31 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR c++/90947
|
||||
* cp-tree.h (type_initializer_zero_p): Declare.
|
||||
* decl.c (reshape_init_array_1): Formatting fix.
|
||||
* tree.c (type_initializer_zero_p): New function. Moved from
|
||||
../tree.c, use next_initializable_field, formatting fix. Return
|
||||
false for TYPE_NON_AGGREGATE_CLASS types.
|
||||
|
||||
2019-10-22 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR tree-optimization/85887
|
||||
|
|
|
@ -7325,6 +7325,11 @@ extern tree cxx_copy_lang_qualifiers (const_tree, const_tree);
|
|||
|
||||
extern void cxx_print_statistics (void);
|
||||
extern bool maybe_warn_zero_as_null_pointer_constant (tree, location_t);
|
||||
/* Analogous to initializer_zerop but also examines the type for
|
||||
which the initializer is being used. Unlike initializer_zerop,
|
||||
considers empty strings to be zero initializers for arrays and
|
||||
non-zero for pointers. */
|
||||
extern bool type_initializer_zero_p (tree, tree);
|
||||
|
||||
/* in ptree.c */
|
||||
extern void cxx_print_xnode (FILE *, tree, int);
|
||||
|
|
|
@ -5850,9 +5850,8 @@ reshape_init_array_1 (tree elt_type, tree max_index, reshape_iter *d,
|
|||
/* Pointers initialized to strings must be treated as non-zero
|
||||
even if the string is empty. */
|
||||
tree init_type = TREE_TYPE (elt_init);
|
||||
if ((POINTER_TYPE_P (elt_type) != POINTER_TYPE_P (init_type)))
|
||||
last_nonzero = index;
|
||||
else if (!type_initializer_zero_p (elt_type, elt_init))
|
||||
if (POINTER_TYPE_P (elt_type) != POINTER_TYPE_P (init_type)
|
||||
|| !type_initializer_zero_p (elt_type, elt_init))
|
||||
last_nonzero = index;
|
||||
|
||||
/* This can happen with an invalid initializer (c++/54501). */
|
||||
|
|
|
@ -5487,6 +5487,68 @@ maybe_warn_zero_as_null_pointer_constant (tree expr, location_t loc)
|
|||
return false;
|
||||
}
|
||||
|
||||
/* Given an initializer INIT for a TYPE, return true if INIT is zero
|
||||
so that it can be replaced by value initialization. This function
|
||||
distinguishes betwen empty strings as initializers for arrays and
|
||||
for pointers (which make it return false). */
|
||||
|
||||
bool
|
||||
type_initializer_zero_p (tree type, tree init)
|
||||
{
|
||||
if (type == error_mark_node || init == error_mark_node)
|
||||
return false;
|
||||
|
||||
STRIP_NOPS (init);
|
||||
|
||||
if (POINTER_TYPE_P (type))
|
||||
return TREE_CODE (init) != STRING_CST && initializer_zerop (init);
|
||||
|
||||
if (TREE_CODE (init) != CONSTRUCTOR)
|
||||
return initializer_zerop (init);
|
||||
|
||||
if (TREE_CODE (type) == ARRAY_TYPE)
|
||||
{
|
||||
tree elt_type = TREE_TYPE (type);
|
||||
elt_type = TYPE_MAIN_VARIANT (elt_type);
|
||||
if (elt_type == char_type_node)
|
||||
return initializer_zerop (init);
|
||||
|
||||
tree elt_init;
|
||||
unsigned HOST_WIDE_INT i;
|
||||
FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (init), i, elt_init)
|
||||
if (!type_initializer_zero_p (elt_type, elt_init))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (TREE_CODE (type) != RECORD_TYPE)
|
||||
return initializer_zerop (init);
|
||||
|
||||
if (TYPE_NON_AGGREGATE_CLASS (type))
|
||||
return false;
|
||||
|
||||
tree fld = TYPE_FIELDS (type);
|
||||
|
||||
tree fld_init;
|
||||
unsigned HOST_WIDE_INT i;
|
||||
FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (init), i, fld_init)
|
||||
{
|
||||
fld = next_initializable_field (fld);
|
||||
if (!fld)
|
||||
return true;
|
||||
|
||||
tree fldtype = TREE_TYPE (fld);
|
||||
if (!type_initializer_zero_p (fldtype, fld_init))
|
||||
return false;
|
||||
|
||||
fld = DECL_CHAIN (fld);
|
||||
if (!fld)
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#if defined ENABLE_TREE_CHECKING && (GCC_VERSION >= 2007)
|
||||
/* Complain that some language-specific thing hanging off a tree
|
||||
node has been accessed improperly. */
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
// PR c++/90947
|
||||
// { dg-do run { target c++11 } }
|
||||
|
||||
#include <atomic>
|
||||
|
||||
static std::atomic<int> a[1] { {1} };
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
if (a[0].load () != 1)
|
||||
__builtin_abort ();
|
||||
}
|
67
gcc/tree.c
67
gcc/tree.c
|
@ -11364,73 +11364,6 @@ initializer_each_zero_or_onep (const_tree expr)
|
|||
}
|
||||
}
|
||||
|
||||
/* Given an initializer INIT for a TYPE, return true if INIT is zero
|
||||
so that it can be replaced by value initialization. This function
|
||||
distinguishes betwen empty strings as initializers for arrays and
|
||||
for pointers (which make it return false). */
|
||||
|
||||
bool
|
||||
type_initializer_zero_p (tree type, tree init)
|
||||
{
|
||||
if (type == error_mark_node || init == error_mark_node)
|
||||
return false;
|
||||
|
||||
STRIP_NOPS (init);
|
||||
|
||||
if (POINTER_TYPE_P (type))
|
||||
return TREE_CODE (init) != STRING_CST && initializer_zerop (init);
|
||||
|
||||
if (TREE_CODE (init) != CONSTRUCTOR)
|
||||
return initializer_zerop (init);
|
||||
|
||||
if (TREE_CODE (type) == ARRAY_TYPE)
|
||||
{
|
||||
tree elt_type = TREE_TYPE (type);
|
||||
elt_type = TYPE_MAIN_VARIANT (elt_type);
|
||||
if (elt_type == char_type_node)
|
||||
return initializer_zerop (init);
|
||||
|
||||
tree elt_init;
|
||||
unsigned HOST_WIDE_INT i;
|
||||
FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (init), i, elt_init)
|
||||
if (!type_initializer_zero_p (elt_type, elt_init))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (TREE_CODE (type) != RECORD_TYPE)
|
||||
return initializer_zerop (init);
|
||||
|
||||
tree fld = TYPE_FIELDS (type);
|
||||
|
||||
tree fld_init;
|
||||
unsigned HOST_WIDE_INT i;
|
||||
FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (init), i, fld_init)
|
||||
{
|
||||
/* Advance to the next member, skipping over everything that
|
||||
canot be initialized (including unnamed bit-fields). */
|
||||
while (TREE_CODE (fld) != FIELD_DECL
|
||||
|| DECL_ARTIFICIAL (fld)
|
||||
|| (DECL_BIT_FIELD (fld) && !DECL_NAME (fld)))
|
||||
{
|
||||
fld = DECL_CHAIN (fld);
|
||||
if (!fld)
|
||||
return true;
|
||||
continue;
|
||||
}
|
||||
|
||||
tree fldtype = TREE_TYPE (fld);
|
||||
if (!type_initializer_zero_p (fldtype, fld_init))
|
||||
return false;
|
||||
|
||||
fld = DECL_CHAIN (fld);
|
||||
if (!fld)
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Check if vector VEC consists of all the equal elements and
|
||||
that the number of elements corresponds to the type of VEC.
|
||||
The function returns first element of the vector
|
||||
|
|
|
@ -4525,12 +4525,6 @@ extern tree first_field (const_tree);
|
|||
extern bool initializer_zerop (const_tree, bool * = NULL);
|
||||
extern bool initializer_each_zero_or_onep (const_tree);
|
||||
|
||||
/* Analogous to initializer_zerop but also examines the type for
|
||||
which the initializer is being used. Unlike initializer_zerop,
|
||||
considers empty strings to be zero initializers for arrays and
|
||||
non-zero for pointers. */
|
||||
extern bool type_initializer_zero_p (tree, tree);
|
||||
|
||||
extern wide_int vector_cst_int_elt (const_tree, unsigned int);
|
||||
extern tree vector_cst_elt (const_tree, unsigned int);
|
||||
|
||||
|
|
Loading…
Reference in New Issue