]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
backport: re PR c++/90947 (Simple lookup table of array of strings is miscompiled)
authorJakub Jelinek <jakub@redhat.com>
Fri, 8 Nov 2019 18:56:42 +0000 (19:56 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Fri, 8 Nov 2019 18:56:42 +0000 (19:56 +0100)
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

gcc/ChangeLog
gcc/cp/ChangeLog
gcc/cp/cp-tree.h
gcc/cp/decl.c
gcc/cp/tree.c
gcc/testsuite/g++.dg/init/array54.C [new file with mode: 0644]
gcc/tree.c
gcc/tree.h

index d1569d5f88f83d9608d78c7ee316d524cc2619e9..96a32d7681aed0a7b349a9b483bc7c997bd899d9 100644 (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
index 6d54b57e9b1eb884c9e507ac7848e44311dd71fb..867b6e5b7f9bc5bfadb868c8c0776ddae2d11053 100644 (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
index e15a07392ca0175606a6bc283755c21ee661e213..050e4b0f3a713473452a93f9155da003076c423c 100644 (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);
index 4878e81021fc7064bb10e37e8dc88d43a772b6a3..444332e53ba8efc6a1323304e1a477a380352e2c 100644 (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).  */
index 1339e9fd204f38ae5f6b9f3765b98e9cf4a5e32a..ae9bfd24cfb6be9938fe35933954b77e17588861 100644 (file)
@@ -5487,6 +5487,68 @@ maybe_warn_zero_as_null_pointer_constant (tree expr, location_t loc)
   return false;
 }
 \f
+/* 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;
+}
+\f
 #if defined ENABLE_TREE_CHECKING && (GCC_VERSION >= 2007)
 /* Complain that some language-specific thing hanging off a tree
    node has been accessed improperly.  */
diff --git a/gcc/testsuite/g++.dg/init/array54.C b/gcc/testsuite/g++.dg/init/array54.C
new file mode 100644 (file)
index 0000000..f6be350
--- /dev/null
@@ -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 ();
+}
index b20781ce00b0c157e4a64d60e7165e31cc8f3db1..374131c74eaa4323486cb5099feb174125693ba7 100644 (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
index 331edfcb1c305729f7990d668bf7c2faf0412dd4..d650511c66f8f9e83645900f11bddc8d9bd6aeb4 100644 (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);