On Wed, Jul 23, 2025 at 04:28:36PM +0000, Qing Zhao wrote:
> 
> 
> > On Jul 23, 2025, at 03:30, Kees Cook <k...@kernel.org> wrote:
> > 
> > 
> > How would GCC want to define the syntax for expressions here? I still
> > think it should be possible to wire up something that matches it in
> > Clang, even if it is a "redundant" syntax within Clang (i.e. Clang can
> > support 2 way to handle expressions, GCC has 1, and Linux will use the
> > common way).
> 
> If that’s acceptable, in GCC alias, we have agreed on the following 
> compromised solution
> after a long and thorough discussion based on one of Bill’s proposal:
> 
> 1. For a lone identifier that refers to a structure field, keep the current 
> counted_by syntax as FAM:
>    
> counted_by (identifier)
> 
> struct s {
>   int len;
>   int *buf __attribute__((counted_by(len))); // this “len” continues to be 
> member ‘len’.
> };
> 
>  2. For simple expressions inside the counted_by attribute, a new attribute 
> will be provided
> 
> counted_by_exp (simple expression)
> 
> Inside this simple expression, forward declarations will be used to resolve 
> the following two issues:
> 
> A. Structure-level scoping that does not exist in C language;
> B. Fields that are declared after the pointer field. 
> 
> For example:
> 
> constexpr int len = 20;
> constexpr int scale = 4;
> struct s {
>   int scale; 
>   int *buf __attribute__((counted_by_exp(int scale; int len; len * scale)));  
>  
>      // len and scale should be the fields inside the structure due to the 
> forward declarations
>   int len;
> };
> 
> 
> I noted that the forward declarations has been strongly rejected in the 
> discussion inside CLANG, but
> didn’t find and understand what’s the root reason for the “strong rejection”. 
> 
> 
> > 
> > The two things I've seen proposed during all of these discussions that
> > look like they should be workable are either:
> > 
> > 1) making expression-using attributes _struct_ attributes, not struct
> > _member_ attributes. (i.e. parsing of the struct has ended)
> 
> This should resolve the issue B I listed in the above, but still cannot 
> resolve the scoping issue.
> If there is a conflict between a global and a field, which one to choose?

If it wasn't forward declared, then isn't it the global then? IIRC
Apple rejected this as too error-prone, and I think it's a reasonable
point: we don't want to add new ambiguities to the language, so we
likely need some way to say "I want exactly the global".

> > 2) using a callback for expressions (no late parsing needed)
> 
> I don’t like this approach due to following reasons:
> 1. both user interface and compiler interface are not friendly;

I think this is improved by my proposal to make the declaration
internally implemented: a bit of "magic", but it has a single syntax, so
there is no ambiguity, and avoids redundancy since the callback will
always have exactly the same prototype pattern:

struct S {
        int array[] __counted_by_callback(how_many);
};

When seeing "how_many" here, a declaration is internally processed as:

static inline size_t __attribute__((pure))
__S_array_counted_by(struct S *instance);

And then after the struct the user can do whatever:

static inline size_t __attribute__((pure))
__S_array_counted_by(struct S *instance) {
{
        return global_var;
}

> 2. Arbitrary function call might be abused by users later;

This part I haven't understood. What does "abused" mean in this case?
The best I can understand is that the "pure" attribute behavior
requirements get violated (though isn't this user error?). Do you mean
something else?

> 3. It’s very hard to be developed to a feature that can be standardized in 
> the future. 

Why is that?

> > 
> > I'm well aware that Apple's implementation will not do either of these,
> > but I'm confident Clang can support the additional syntax -- it should
> > be possible to provide both, especially since it would be a "GCC
> > compatibility" issue. :)
> 
> If Clang can provide a GCC compatible counted_by_exp attribute, then the 
> problem can be 
> Resolved for linux kernel.

Agreed. AFAICT, the infrastructure will exist in Clang already to
support counted_by_exp(); it is just a different way to specify the same
thing.

-- 
Kees Cook

Reply via email to