Skip to content

Commit cff0a46

Browse files
authored
[Clang][counted_by] Refactor __builtin_dynamic_object_size on FAMs (#122198)
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. Calculate the flexible array member's object size using these formulae (note: if the calculation is negative, we return 0.): struct p; struct s { /* ... */ int count; struct p *array[] __attribute__((counted_by(count))); }; 1) 'ptr->array': count = ptr->count; flexible_array_member_base_size = sizeof (*ptr->array); flexible_array_member_size = count * flexible_array_member_base_size; if (flexible_array_member_size < 0) return 0; return flexible_array_member_size; 2) '&ptr->array[idx]': count = ptr->count; index = idx; flexible_array_member_base_size = sizeof (*ptr->array); flexible_array_member_size = count * flexible_array_member_base_size; index_size = index * flexible_array_member_base_size; if (flexible_array_member_size < 0 || index < 0) return 0; return flexible_array_member_size - index_size; 3) '&ptr->field': count = ptr->count; sizeof_struct = sizeof (struct s); flexible_array_member_base_size = sizeof (*ptr->array); flexible_array_member_size = count * flexible_array_member_base_size; field_offset = offsetof (struct s, field); offset_diff = sizeof_struct - field_offset; if (flexible_array_member_size < 0) return 0; return offset_diff + flexible_array_member_size; 4) '&ptr->field_array[idx]': count = ptr->count; index = idx; sizeof_struct = sizeof (struct s); flexible_array_member_base_size = sizeof (*ptr->array); flexible_array_member_size = count * flexible_array_member_base_size; field_base_size = sizeof (*ptr->field_array); field_offset = offsetof (struct s, field) field_offset += index * field_base_size; offset_diff = sizeof_struct - field_offset; if (flexible_array_member_size < 0 || index < 0) return 0; return offset_diff + flexible_array_member_size; --------- Signed-off-by: Bill Wendling <[email protected]>
1 parent a51798e commit cff0a46

File tree

3 files changed

+950
-488
lines changed

3 files changed

+950
-488
lines changed

0 commit comments

Comments
 (0)