aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorDavid Malcolm <dmalcolm@redhat.com>2020-08-15 15:34:21 -0400
committerDavid Malcolm <dmalcolm@redhat.com>2020-08-17 14:45:00 -0400
commit35c5f8fb432c8e68af68ab48c8d3107e7839775e (patch)
treeb1da377e692ddf911a2e70a51153f32383ead30d /gcc
parent9e026191547225ca02c1eda91f898271fced3bbf (diff)
downloadgcc-35c5f8fb432c8e68af68ab48c8d3107e7839775e.zip
gcc-35c5f8fb432c8e68af68ab48c8d3107e7839775e.tar.gz
gcc-35c5f8fb432c8e68af68ab48c8d3107e7839775e.tar.bz2
analyzer: handle &STRING_CST in constant pool initializers [PR96642]
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.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/analyzer/store.cc21
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/pr96642.c10
2 files changed, 28 insertions, 3 deletions
diff --git a/gcc/analyzer/store.cc b/gcc/analyzer/store.cc
index 2329200..5af86d0 100644
--- a/gcc/analyzer/store.cc
+++ b/gcc/analyzer/store.cc
@@ -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
index 0000000..117aa04
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/pr96642.c
@@ -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,
+ };
+}