Skip to content

Commit 9610694

Browse files
committed
[Clang][counted_by] Refactor __builtin_dynamic_object_size on FAMs
Refactoring of how __builtin_dynamic_object_size() is calculated for flexible array members (in preparation for adding support for the 'counted_by' attribute on pointers in structs). The only functionality change is that we use the already emitted Expr code to build our calculations off of rather than re-emitting the Expr. That allows the 'StructFieldAccess' visitor to sift through all casts and ArraySubscriptExprs to find the first MemberExpr. We build our GEPs and calculate offsets based off of relative distances from that MemberExpr. The testcase passes execution tests. There are four categories to support: struct p; struct s { /* ... */ int count; struct p *array[] __attribute__((counted_by(count))); }; 1) Object size of full flexible array member's size 'ptr->array': size_t count = (size_t) ptr->count; size_t flexible_array_member_base_size = sizeof (*ptr->array); size_t flexible_array_member_size = count * flexible_array_member_base_size; return flexible_array_member_size; 2) Object size from partial flexible array member '&ptr->array[idx]': size_t count = (size_t) ptr->count; size_t index = (size_t) idx; size_t flexible_array_member_base_size = sizeof (*ptr->array); size_t flexible_array_member_size = count * flexible_array_member_base_size; size_t index_size = index * flexible_array_member_base_size; return flexible_array_member_size - index_size; 3) Object size from '&ptr->field': size_t count = (size_t) ptr->count; size_t sizeof_struct = sizeof (struct s); size_t flexible_array_member_base_size = sizeof (*ptr->array); size_t flexible_array_member_size = count * flexible_array_member_base_size; size_t field_offset = offsetof (struct s, field); size_t offset_diff = sizeof_struct - field_offset; return flexible_array_member_size + offset_diff; 4) Object size from '&ptr->field[idx]': size_t count = (size_t) ptr->count; size_t index = (size_t) idx; size_t sizeof_struct = sizeof (struct s); size_t field_base_size = sizeof (*ptr->field); size_t flexible_array_member_base_size = sizeof (*ptr->array); size_t flexible_array_member_size = count * flexible_array_member_base_size; size_t field_offset = offsetof (struct s, field) + index * field_base_size; size_t offset_diff = sizeof_struct - field_offset; return offset_diff + flexible_array_member_size; Signed-off-by: Bill Wendling <[email protected]>
1 parent 1855333 commit 9610694

File tree

3 files changed

+809
-526
lines changed

3 files changed

+809
-526
lines changed

0 commit comments

Comments
 (0)