[committed] analyzer: fix region::get_bit_size for bitfields

Message ID 20210608185514.1047822-1-dmalcolm@redhat.com
State New
Headers show
Series
  • [committed] analyzer: fix region::get_bit_size for bitfields
Related show

Commit Message

Jason Merrill via Gcc-patches June 8, 2021, 6:55 p.m.
Successfully bootstrapped & regrtested on x86_64-pc-linux-gnu.
Pushed to trunk as c957d38044d7eb6a45f57a8a9f707c3c0a798e9f.

gcc/analyzer/ChangeLog:
	* analyzer.h (int_size_in_bits): New decl.
	* region.cc (int_size_in_bits): New function.
	(region::get_bit_size): Reimplement in terms of the above.

Signed-off-by: David Malcolm <dmalcolm@redhat.com>

---
 gcc/analyzer/analyzer.h |  2 ++
 gcc/analyzer/region.cc  | 33 +++++++++++++++++++++++++++++----
 2 files changed, 31 insertions(+), 4 deletions(-)

-- 
2.26.3

Patch

diff --git a/gcc/analyzer/analyzer.h b/gcc/analyzer/analyzer.h
index fb568e44d38..525eb06c3b5 100644
--- a/gcc/analyzer/analyzer.h
+++ b/gcc/analyzer/analyzer.h
@@ -144,6 +144,8 @@  typedef offset_int bit_offset_t;
 typedef offset_int bit_size_t;
 typedef offset_int byte_size_t;
 
+extern bool int_size_in_bits (const_tree type, bit_size_t *out);
+
 /* The location of a region expressesd as an offset relative to a
    base region.  */
 
diff --git a/gcc/analyzer/region.cc b/gcc/analyzer/region.cc
index 6db1fc91afd..5f246df7dfb 100644
--- a/gcc/analyzer/region.cc
+++ b/gcc/analyzer/region.cc
@@ -208,6 +208,29 @@  region::get_byte_size (byte_size_t *out) const
   return true;
 }
 
+/* If the size of TYPE (in bits) is constant, write it to *OUT
+   and return true.
+   Otherwise return false.  */
+
+bool
+int_size_in_bits (const_tree type, bit_size_t *out)
+{
+  if (INTEGRAL_TYPE_P (type))
+    {
+      *out = TYPE_PRECISION (type);
+      return true;
+    }
+
+  tree sz = TYPE_SIZE (type);
+  if (sz && tree_fits_uhwi_p (sz))
+    {
+      *out = TREE_INT_CST_LOW (sz);
+      return true;
+    }
+  else
+    return false;
+}
+
 /* If the size of this region (in bits) is known statically, write it to *OUT
    and return true.
    Otherwise return false.  */
@@ -215,11 +238,13 @@  region::get_byte_size (byte_size_t *out) const
 bool
 region::get_bit_size (bit_size_t *out) const
 {
-  byte_size_t byte_size;
-  if (!get_byte_size (&byte_size))
+  tree type = get_type ();
+
+  /* Bail out e.g. for heap-allocated regions.  */
+  if (!type)
     return false;
-  *out = byte_size * BITS_PER_UNIT;
-  return true;
+
+  return int_size_in_bits (type, out);
 }
 
 /* Get the field within RECORD_TYPE at BIT_OFFSET.  */