diff options
author | David Malcolm <dmalcolm@redhat.com> | 2021-06-08 14:45:07 -0400 |
---|---|---|
committer | David Malcolm <dmalcolm@redhat.com> | 2021-06-08 14:45:07 -0400 |
commit | c957d38044d7eb6a45f57a8a9f707c3c0a798e9f (patch) | |
tree | bc920e7cce354c801a55c2e0b620f8e45634d586 /gcc | |
parent | 6b400aef1bdc84bbdf5011caff3fe5f82c68d253 (diff) | |
download | gcc-c957d38044d7eb6a45f57a8a9f707c3c0a798e9f.zip gcc-c957d38044d7eb6a45f57a8a9f707c3c0a798e9f.tar.gz gcc-c957d38044d7eb6a45f57a8a9f707c3c0a798e9f.tar.bz2 |
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 <dmalcolm@redhat.com>
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/analyzer/analyzer.h | 2 | ||||
-rw-r--r-- | 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. */ |