aboutsummaryrefslogtreecommitdiff
path: root/gcc/analyzer
diff options
context:
space:
mode:
authorMartin Liska <mliska@suse.cz>2022-09-06 06:52:14 +0200
committerMartin Liska <mliska@suse.cz>2022-09-06 06:52:14 +0200
commit918bc838c2803f08e4d7ccd179396d48cb8ec804 (patch)
tree2496c039b51fd33ee4309d910f0f6ce44cd5f749 /gcc/analyzer
parent8de5354e2cf4e6ea750ea92c7162d61b1b796f76 (diff)
parent47d2dcd1397bf02b79515c39438e0ea9898f9056 (diff)
downloadgcc-918bc838c2803f08e4d7ccd179396d48cb8ec804.zip
gcc-918bc838c2803f08e4d7ccd179396d48cb8ec804.tar.gz
gcc-918bc838c2803f08e4d7ccd179396d48cb8ec804.tar.bz2
Merge branch 'master' into devel/sphinx
Diffstat (limited to 'gcc/analyzer')
-rw-r--r--gcc/analyzer/ChangeLog14
-rw-r--r--gcc/analyzer/region-model-impl-calls.cc16
-rw-r--r--gcc/analyzer/region-model.cc29
-rw-r--r--gcc/analyzer/region-model.h3
-rw-r--r--gcc/analyzer/region.cc10
-rw-r--r--gcc/analyzer/region.h2
6 files changed, 71 insertions, 3 deletions
diff --git a/gcc/analyzer/ChangeLog b/gcc/analyzer/ChangeLog
index 01cf9d8..3ad3096 100644
--- a/gcc/analyzer/ChangeLog
+++ b/gcc/analyzer/ChangeLog
@@ -1,3 +1,17 @@
+2022-09-05 Tim Lange <mail@tim-lange.me>
+
+ * region-model-impl-calls.cc (region_model::impl_call_strcpy):
+ Handle the constant string case.
+ * region-model.cc (region_model::get_string_size):
+ New function to get the string size from a region or svalue.
+ * region-model.h (class region_model): Add get_string_size.
+
+2022-09-05 Tim Lange <mail@tim-lange.me>
+
+ * region.cc (cast_region::get_relative_concrete_offset):
+ New overloaded method.
+ * region.h: Add cast_region::get_relative_concrete_offset.
+
2022-08-22 Martin Liska <mliska@suse.cz>
* region-model.cc: Add missing final keyword.
diff --git a/gcc/analyzer/region-model-impl-calls.cc b/gcc/analyzer/region-model-impl-calls.cc
index 8eebd12..3790eaf 100644
--- a/gcc/analyzer/region-model-impl-calls.cc
+++ b/gcc/analyzer/region-model-impl-calls.cc
@@ -1019,13 +1019,23 @@ region_model::impl_call_strcpy (const call_details &cd)
const svalue *dest_sval = cd.get_arg_svalue (0);
const region *dest_reg = deref_rvalue (dest_sval, cd.get_arg_tree (0),
cd.get_ctxt ());
+ const svalue *src_sval = cd.get_arg_svalue (1);
+ const region *src_reg = deref_rvalue (src_sval, cd.get_arg_tree (1),
+ cd.get_ctxt ());
+ const svalue *src_contents_sval = get_store_value (src_reg,
+ cd.get_ctxt ());
cd.maybe_set_lhs (dest_sval);
- check_region_for_write (dest_reg, cd.get_ctxt ());
+ /* Try to get the string size if SRC_REG is a string_region. */
+ const svalue *copied_bytes_sval = get_string_size (src_reg);
+ /* Otherwise, check if the contents of SRC_REG is a string. */
+ if (copied_bytes_sval->get_kind () == SK_UNKNOWN)
+ copied_bytes_sval = get_string_size (src_contents_sval);
- /* For now, just mark region's contents as unknown. */
- mark_region_as_unknown (dest_reg, cd.get_uncertainty ());
+ const region *sized_dest_reg
+ = m_mgr->get_sized_region (dest_reg, NULL_TREE, copied_bytes_sval);
+ set_value (sized_dest_reg, src_contents_sval, cd.get_ctxt ());
}
/* Handle the on_call_pre part of "strlen". */
diff --git a/gcc/analyzer/region-model.cc b/gcc/analyzer/region-model.cc
index 5a64c00..e84087a 100644
--- a/gcc/analyzer/region-model.cc
+++ b/gcc/analyzer/region-model.cc
@@ -3218,6 +3218,35 @@ region_model::get_capacity (const region *reg) const
return m_mgr->get_or_create_unknown_svalue (sizetype);
}
+/* Return the string size, including the 0-terminator, if SVAL is a
+ constant_svalue holding a string. Otherwise, return an unknown_svalue. */
+
+const svalue *
+region_model::get_string_size (const svalue *sval) const
+{
+ tree cst = sval->maybe_get_constant ();
+ if (!cst || TREE_CODE (cst) != STRING_CST)
+ return m_mgr->get_or_create_unknown_svalue (size_type_node);
+
+ tree out = build_int_cst (size_type_node, TREE_STRING_LENGTH (cst));
+ return m_mgr->get_or_create_constant_svalue (out);
+}
+
+/* Return the string size, including the 0-terminator, if REG is a
+ string_region. Otherwise, return an unknown_svalue. */
+
+const svalue *
+region_model::get_string_size (const region *reg) const
+{
+ const string_region *str_reg = dyn_cast <const string_region *> (reg);
+ if (!str_reg)
+ return m_mgr->get_or_create_unknown_svalue (size_type_node);
+
+ tree cst = str_reg->get_string_cst ();
+ tree out = build_int_cst (size_type_node, TREE_STRING_LENGTH (cst));
+ return m_mgr->get_or_create_constant_svalue (out);
+}
+
/* If CTXT is non-NULL, use it to warn about any problems accessing REG,
using DIR to determine if this access is a read or write. */
diff --git a/gcc/analyzer/region-model.h b/gcc/analyzer/region-model.h
index 7ce832f..a1f2165 100644
--- a/gcc/analyzer/region-model.h
+++ b/gcc/analyzer/region-model.h
@@ -793,6 +793,9 @@ class region_model
const svalue *get_capacity (const region *reg) const;
+ const svalue *get_string_size (const svalue *sval) const;
+ const svalue *get_string_size (const region *reg) const;
+
/* Implemented in sm-malloc.cc */
void on_realloc_with_move (const call_details &cd,
const svalue *old_ptr_sval,
diff --git a/gcc/analyzer/region.cc b/gcc/analyzer/region.cc
index f4aba6b..9c8279b 100644
--- a/gcc/analyzer/region.cc
+++ b/gcc/analyzer/region.cc
@@ -1556,6 +1556,16 @@ cast_region::dump_to_pp (pretty_printer *pp, bool simple) const
}
}
+/* Implementation of region::get_relative_concrete_offset vfunc
+ for cast_region. */
+
+bool
+cast_region::get_relative_concrete_offset (bit_offset_t *out) const
+{
+ *out = (int) 0;
+ return true;
+}
+
/* class heap_allocated_region : public region. */
/* Implementation of region::dump_to_pp vfunc for heap_allocated_region. */
diff --git a/gcc/analyzer/region.h b/gcc/analyzer/region.h
index d37584b..34ce1fa 100644
--- a/gcc/analyzer/region.h
+++ b/gcc/analyzer/region.h
@@ -1087,6 +1087,8 @@ public:
void accept (visitor *v) const final override;
void dump_to_pp (pretty_printer *pp, bool simple) const final override;
+ bool get_relative_concrete_offset (bit_offset_t *out) const final override;
+
const region *get_original_region () const { return m_original_region; }
private: