analyzer: handle &STRING_CST in constant pool initializers [PR96642]
authorDavid Malcolm <dmalcolm@redhat.com>
Sat, 15 Aug 2020 19:34:21 +0000 (15:34 -0400)
committerDavid Malcolm <dmalcolm@redhat.com>
Mon, 17 Aug 2020 18:45:00 +0000 (14:45 -0400)
In r11-2708-g2867118ddda9b56d991c16022f7d3d634ed08313 I added support to
the analyzer for initialization from var_decls in the global constant
pool.  However, that commit didn't support initialization from
ADDR_EXPR of a STRING_CST leading to an ICE seen in data-model-1.c and
pr94639.c on arm and powerpc64 at least, and as PR analyzer/96642 on
x86_64 at least.

This patch adds support for such initializers, fixing the ICE.

gcc/analyzer/ChangeLog:
PR analyzer/96642
* store.cc (get_svalue_for_ctor_val): New.
(binding_map::apply_ctor_to_region): Call it.

gcc/testsuite/ChangeLog:
PR analyzer/96642
* gcc.dg/analyzer/pr96642.c: New test.

gcc/analyzer/store.cc
gcc/testsuite/gcc.dg/analyzer/pr96642.c [new file with mode: 0644]

index 2329200..5af86d0 100644 (file)
@@ -391,6 +391,22 @@ get_subregion_within_ctor (const region *parent_reg, tree index,
     }
 }
 
+/* Get the svalue for VAL, a non-CONSTRUCTOR value within a CONSTRUCTOR.  */
+
+static const svalue *
+get_svalue_for_ctor_val (tree val, region_model_manager *mgr)
+{
+  if (TREE_CODE (val) == ADDR_EXPR)
+    {
+      gcc_assert (TREE_CODE (TREE_OPERAND (val, 0)) == STRING_CST);
+      const string_region *str_reg
+       = mgr->get_region_for_string (TREE_OPERAND (val, 0));
+      return mgr->get_ptr_svalue (TREE_TYPE (val), str_reg);
+    }
+  gcc_assert (CONSTANT_CLASS_P (val));
+  return mgr->get_or_create_constant_svalue (val);
+}
+
 /* Bind values from CONSTRUCTOR to this map, relative to
    PARENT_REG's relationship to its base region.  */
 
@@ -415,12 +431,11 @@ binding_map::apply_ctor_to_region (const region *parent_reg, tree ctor,
        apply_ctor_to_region (child_reg, val, mgr);
       else
        {
-         gcc_assert (CONSTANT_CLASS_P (val));
-         const svalue *cst_sval = mgr->get_or_create_constant_svalue (val);
+         const svalue *sval = get_svalue_for_ctor_val (val, mgr);
          const binding_key *k
            = binding_key::make (mgr->get_store_manager (), child_reg,
                                 BK_direct);
-         put (k, cst_sval);
+         put (k, sval);
        }
     }
 }
diff --git a/gcc/testsuite/gcc.dg/analyzer/pr96642.c b/gcc/testsuite/gcc.dg/analyzer/pr96642.c
new file mode 100644 (file)
index 0000000..117aa04
--- /dev/null
@@ -0,0 +1,10 @@
+void
+ut (void)
+{
+  struct {
+    char *cc;
+  } sr[] = {
+    0, 0, 0, 0, 0, 0, 0, 0, 0, "", "", 0, "", 0, 0, "",
+    0, 0, "", 0, 0, "", 0, 0, "", 0, 0, "", 0, 0, 0, 0, 0,
+  };
+}