On Wed, Jul 16, 2014 at 9:24 AM, Jeff Layton <jeff.layton@xxxxxxxxxxxxxxx> wrote: > > Thanks, I think I might have found it. init_ctype tries to correct for > the fact that bits_to_bytes rounds up instead of down. With the > corrected function, we don't need that correction anymore. > > I'll send the v2 patch soon, which seems to do the right thing. > Great catch. I was looking at the it last night but haven't found the cause. It was not cause by the array element alignment, which I attach a purposed patch. I will apply your V2 patch and the fix for the array. Every thing should be happy now. Chris round up for 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@xxxxxxxxxxx> diff --git a/evaluate.c b/evaluate.c index 7ce8c55..03992d0 100644 --- a/evaluate.c +++ b/evaluate.c @@ -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; diff --git a/symbol.c b/symbol.c index 1a3df63..a697627 100644 --- a/symbol.c +++ b/symbol.c @@ -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."); diff --git a/target.h b/target.h index 140df3c..78c85cf 100644 --- a/target.h +++ b/target.h @@ -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 -- To unsubscribe from this list: send the line "unsubscribe linux-sparse" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html