On Sat, Sep 14, 2024 at 08:58:28PM +0200, Jakub Jelinek wrote:
> if (has_counted_by_object (e_p->value))
> expr.value = get_counted_by_ref (e_p->value);
> else if (in_typeof && TREE_CODE (e_p->value) == COMPONENT_REF)
> {
> tree counted_by_type = NULL_TREE;
> tree arg = (*cexpr_
> if (build_counted_by_ref (TREE_OPERAND (e_p->value, 0),
> TREE_OPERAND (e_p->value, 1),
> &counted_by_type))
> expr.value
> = build_zero_cst (build_pointer_type (counted_by_type));
> else
> expr.value = null_pointer_node;
> }
> else
> expr.value = null_pointer_node;
>
> (plus make build_counted_by_ref non-static and add prototype).
>
> Completely untested.
Note, the above I think ought to work with say
__typeof (__builtin_counted_by_ref (obj->fam))
or
__alignof (*__builtin_counted_by_ref (obj->fam))
but will not work with say
struct with_fam obj;
void foo () {
...
__typeof (char [__builtin_counted_by_ref (obj.fam) == &obj.size ? 1 : -1])
...
}
etc. (and similar for alignof; something like that should go into the
testsuite).
So maybe better
tree arg = e_p->value;
tree f;
if ((in_typeof || in_alignof)
&& TREE_CODE (arg) == COMPONENT_REF
&& (f = TREE_OPERAND (arg, 1))
&& TREE_CODE (f) == FIELD_DECL
&& c_flexible_array_member_type_p (TREE_TYPE (f))
&& lookup_attribute ("counted_by", DECL_ATTRIBUTES (f))
&& DECL_NAME (f))
arg = build_component_ref (EXPR_LOCATION (arg),
TREE_OPERAND (arg, 0),
DECL_NAME (f), UNKNOWN_LOCATION,
UNKNOWN_LOCATION, true);
if (has_counted_by_object (arg))
expr.value = get_counted_by_ref (arg);
else
expr.value = null_pointer_node;
Jakub