From: David Malcolm <dmalcolm@redhat.com>
To: gcc-patches@gcc.gnu.org
Cc: David Malcolm <dmalcolm@redhat.com>
Subject: [pushed] analyzer: fix ICE on negative values for size_t [PR114472]
Date: Wed, 10 Apr 2024 16:56:19 -0400 [thread overview]
Message-ID: <20240410205619.335838-1-dmalcolm@redhat.com> (raw)
I made several attempts to fix this properly, but for now apply
a band-aid to at least prevent crashing on such cases.
Successfully bootstrapped & regrtested on x86_64-pc-linux-gnu.
Successful run of analyzer integration tests on x86_64-pc-linux-gnu.
Pushed to trunk as r14-9902-g4a94551d7eaaf7.
gcc/analyzer/ChangeLog:
PR analyzer/114472
* access-diagram.cc (bit_size_expr::maybe_get_formatted_str):
Reject attempts to print sizes that are too large.
* region.cc (region_offset::calc_symbolic_bit_offset): Use a
typeless svalue for the bit offset.
* store.cc (bit_range::intersects_p): Replace assertion with
test.
(bit_range::exceeds_p): Likewise.
(bit_range::falls_short_of_p): Likewise.
gcc/testsuite/ChangeLog:
* c-c++-common/analyzer/out-of-bounds-pr114472.c: New test.
Signed-off-by: David Malcolm <dmalcolm@redhat.com>
---
gcc/analyzer/access-diagram.cc | 4 ++++
gcc/analyzer/region.cc | 2 +-
gcc/analyzer/store.cc | 20 +++++++++++++++----
.../analyzer/out-of-bounds-pr114472.c | 17 ++++++++++++++++
4 files changed, 38 insertions(+), 5 deletions(-)
create mode 100644 gcc/testsuite/c-c++-common/analyzer/out-of-bounds-pr114472.c
diff --git a/gcc/analyzer/access-diagram.cc b/gcc/analyzer/access-diagram.cc
index 4cb6570e90b9..873205c46499 100644
--- a/gcc/analyzer/access-diagram.cc
+++ b/gcc/analyzer/access-diagram.cc
@@ -373,6 +373,8 @@ bit_size_expr::maybe_get_formatted_str (text_art::style_manager &sm,
if (tree cst = num_bytes->maybe_get_constant ())
{
byte_size_t concrete_num_bytes = wi::to_offset (cst);
+ if (!wi::fits_uhwi_p (concrete_num_bytes))
+ return nullptr;
if (concrete_num_bytes == 1)
return ::make_unique <text_art::styled_string>
(fmt_styled_string (sm, concrete_single_byte_fmt,
@@ -396,6 +398,8 @@ bit_size_expr::maybe_get_formatted_str (text_art::style_manager &sm,
else if (tree cst = m_num_bits.maybe_get_constant ())
{
bit_size_t concrete_num_bits = wi::to_offset (cst);
+ if (!wi::fits_uhwi_p (concrete_num_bits))
+ return nullptr;
if (concrete_num_bits == 1)
return ::make_unique <text_art::styled_string>
(fmt_styled_string (sm, concrete_single_bit_fmt,
diff --git a/gcc/analyzer/region.cc b/gcc/analyzer/region.cc
index 705816b62454..7d79b45563fd 100644
--- a/gcc/analyzer/region.cc
+++ b/gcc/analyzer/region.cc
@@ -89,7 +89,7 @@ region_offset::calc_symbolic_bit_offset (region_model_manager *mgr) const
m_sym_offset, bits_per_byte);
}
else
- return *mgr->get_or_create_int_cst (size_type_node, m_offset);
+ return *mgr->get_or_create_int_cst (NULL_TREE, m_offset);
}
const svalue *
diff --git a/gcc/analyzer/store.cc b/gcc/analyzer/store.cc
index e85a19647f7e..a36de13c1743 100644
--- a/gcc/analyzer/store.cc
+++ b/gcc/analyzer/store.cc
@@ -290,7 +290,10 @@ bit_range::intersects_p (const bit_range &other,
bit_offset_t overlap_next
= MIN (get_next_bit_offset (),
other.get_next_bit_offset ());
- gcc_assert (overlap_next > overlap_start);
+ if (overlap_next <= overlap_start)
+ /* If this has happened, some kind of overflow has happened in
+ our arithmetic. For now, reject such cases. */
+ return false;
bit_range abs_overlap_bits (overlap_start, overlap_next - overlap_start);
*out_this = abs_overlap_bits - get_start_bit_offset ();
*out_other = abs_overlap_bits - other.get_start_bit_offset ();
@@ -316,7 +319,10 @@ bit_range::intersects_p (const bit_range &other,
other.get_start_bit_offset ());
bit_offset_t overlap_next = MIN (get_next_bit_offset (),
other.get_next_bit_offset ());
- gcc_assert (overlap_next > overlap_start);
+ if (overlap_next <= overlap_start)
+ /* If this has happened, some kind of overflow has happened in
+ our arithmetic. For now, reject such cases. */
+ return false;
*out_num_overlap_bits = overlap_next - overlap_start;
return true;
}
@@ -339,7 +345,10 @@ bit_range::exceeds_p (const bit_range &other,
bit_offset_t start = MAX (get_start_bit_offset (),
other.get_next_bit_offset ());
bit_offset_t size = get_next_bit_offset () - start;
- gcc_assert (size > 0);
+ if (size <= 0)
+ /* If this has happened, some kind of overflow has happened in
+ our arithmetic. For now, reject such cases. */
+ return false;
out_overhanging_bit_range->m_start_bit_offset = start;
out_overhanging_bit_range->m_size_in_bits = size;
return true;
@@ -362,7 +371,10 @@ bit_range::falls_short_of_p (bit_offset_t offset,
/* THIS falls short of OFFSET. */
bit_offset_t start = get_start_bit_offset ();
bit_offset_t size = MIN (offset, get_next_bit_offset ()) - start;
- gcc_assert (size > 0);
+ if (size <= 0)
+ /* If this has happened, some kind of overflow has happened in
+ our arithmetic. For now, reject such cases. */
+ return false;
out_fall_short_bits->m_start_bit_offset = start;
out_fall_short_bits->m_size_in_bits = size;
return true;
diff --git a/gcc/testsuite/c-c++-common/analyzer/out-of-bounds-pr114472.c b/gcc/testsuite/c-c++-common/analyzer/out-of-bounds-pr114472.c
new file mode 100644
index 000000000000..ef9e7711a2e4
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/analyzer/out-of-bounds-pr114472.c
@@ -0,0 +1,17 @@
+/* Verify we don't ICE on cases involving very large values for size. */
+
+char s, d;
+
+void
+foo(void)
+{
+ __builtin_strncpy(&d, &s + 3, -1); /* { dg-warning "Wstringop-overflow" } */
+ __builtin_strncpy(&d + 3, &s, -1); /* { dg-warning "Wstringop-overflow" } */
+}
+
+void
+bar(void)
+{
+ __builtin_strncpy(&d, &s - 3, -1); /* { dg-warning "Wstringop-overflow" } */
+ __builtin_strncpy(&d - 3, &s, -1); /* { dg-warning "Wstringop-overflow" } */
+}
--
2.26.3
reply other threads:[~2024-04-10 20:56 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20240410205619.335838-1-dmalcolm@redhat.com \
--to=dmalcolm@redhat.com \
--cc=gcc-patches@gcc.gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).