diff options
author | Christopher Li <sparse@chrisli.org> | 2014-07-15 23:20:09 -0700 |
---|---|---|
committer | Christopher Li <sparse@chrisli.org> | 2014-07-17 08:58:28 -0700 |
commit | 09e7a493cf3d92a6ccd7611b69bd41cb5727f765 (patch) | |
tree | a8e8f1e972bb06bbea3ee5d44ddb6ae38d99fb1f | |
parent | b3e9d87c6a98bde0c95bc8badfde75c06661738b (diff) | |
download | sparse-09e7a493cf3d92a6ccd7611b69bd41cb5727f765.tar.gz |
round up the array element size to byte align
When layout the array element, the element size should
round up to byte align.
Signed-off-by: Christopher Li <sparse@chrisli.org>
-rw-r--r-- | evaluate.c | 2 | ||||
-rw-r--r-- | symbol.c | 3 | ||||
-rw-r--r-- | target.h | 8 |
3 files changed, 11 insertions, 2 deletions
@@ -2302,7 +2302,7 @@ static struct expression *check_designators(struct expression *e, } type = ctype->ctype.base_type; if (ctype->bit_size >= 0 && type->bit_size >= 0) { - unsigned offset = e->idx_to * type->bit_size; + unsigned offset = array_element_offset(type->bit_size, e->idx_to); if (offset >= ctype->bit_size) { err = "index out of bounds in"; break; @@ -234,7 +234,8 @@ static struct symbol * examine_array_type(struct symbol *sym) return sym; if (array_size) { - bit_size = base_type->bit_size * get_expression_value_silent(array_size); + bit_size = array_element_offset(base_type->bit_size, + get_expression_value_silent(array_size)); if (array_size->type != EXPR_VALUE) { if (Wvla) warning(array_size->pos, "Variable length array is used."); @@ -57,4 +57,12 @@ static inline int bytes_to_bits(int bytes) return bytes * bits_in_char; } +static inline unsigned long array_element_offset(unsigned long base_bits, int idx) +{ + int fragment = base_bits % bits_in_char; + if (fragment) + base_bits += bits_in_char - fragment; + return base_bits * idx; +} + #endif |