On Wed, Apr 30, 2025 at 08:56:57AM +0200, Jakub Jelinek wrote: > On Mon, Apr 28, 2025 at 07:27:31PM +0200, Josef Melcr wrote: > > As for the attribute, I am honestly not too sure about what to do, as clang > > is > > not consistent in with its own indexing, be it with the unknown values, or > > with > > 'this'. I've tried to remain consistent with GCC's indexing style. I guess > > I'll > > leave up to you and the other maintainers to decide. I can implement clangs > > version 1:1, put the attribute in our namespace or rename it. I don't mind > > either way. Another option would be to patch clang to get in line with the > > rest > > of its attributes. It seems like the best option to me, as it would make > > being > > consistent way easier, but it would be problematic, as all code using this > > attribute would need to be updated. > > I'll talk to C/C++ FE maintainers what they think.
So, I had a closer look at the clang callback attribute. Seems it has been introduced in clang 9 (so 2019-ish) and doesn't match the usual 1/2 based counting which is used for nonnull/format etc. attributes. constexpr int c = 3; __attribute__((callback (1, 2, 3))) int foo (void (*) (void *, int), void *a, int b); // Ok __attribute__((callback (1, 2))) int bar (int, void *); // error: 'callback' attribute callee does not have function type __attribute__((callback (1, 2))) int baz (void (*) (void *), int); // Accepted, no checking is done on whether the passed in arguments types match __attribute__((callback (-2 + c, 2))) int freddy (void (*) (void *), void *); // Ok __attribute__((callback (1, c))) int qux (void (*) (void *), int, void *); // 'callback' attribute argument 'c' is not a known function parameter __attribute__((callback (1, c + 1))) int corge (void (*) (void *), int, void *); // Parsing error __attribute__((callback (c, d, e))) int garply (void (*c) (void *, int), void *d, int e); // like (1, 2, 3) __attribute__((callback (1, -1, __))) int boo (void (*) (void *, int), void *, int); struct S { __attribute__((callback (1, 2, 3))) int foo (void (*) (void *, int), void *a, int b); // Ok (so no 2 based with this 1, but 1 based with this 0 }; -1 or __ identifier stands for argument passed from somewhere else or modified on the way. https://releases.llvm.org/9.0.0/tools/clang/docs/AttributeReference.html#callback https://clang.llvm.org/docs/AttributeReference.html#callback are their docs on it. Thus, the question is whether we want to implement the callback attribute with these design inconsistencies and flaws, or perhaps with minor tweaks (e.g. allow c + 1 to be processed like (c + 1) and only leave identifiers alone for argument names), or whether __attribute__((cleanup ())) should have the clang behavior and [[gnu::cleanup (...)]]] something different, or whether we should go for some different attribute name altogether (e.g. gnu_cleanup) or just different name for the __attribute__ form and for [[]] form use gnu::cleanup. Thoughts on this? Jakub