Commit 9610694
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- clang
- lib/CodeGen
- test/CodeGen
3 files changed
+809
-526
lines changed
0 commit comments