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:
Jakub Jelinek 2019-11-08 19:56:42 +01:00 committed by Jakub Jelinek
parent 357a65e1ce
commit 8af68eba76
8 changed files with 97 additions and 76 deletions

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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). */

View File

@ -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. */

View File

@ -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 ();
}

View File

@ -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

View File

@ -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);