From c957d38044d7eb6a45f57a8a9f707c3c0a798e9f Mon Sep 17 00:00:00 2001 From: David Malcolm Date: Tue, 8 Jun 2021 14:45:07 -0400 Subject: [PATCH] analyzer: fix region::get_bit_size for bitfields 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 --- gcc/analyzer/analyzer.h | 2 ++ gcc/analyzer/region.cc | 33 +++++++++++++++++++++++++++++---- 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/gcc/analyzer/analyzer.h b/gcc/analyzer/analyzer.h index fb568e4..525eb06 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 6db1fc9..5f246df 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. */ -- 2.7.4