> On Jul 28, 2025, at 16:09, Martin Uecker <ma.uec...@gmail.com> wrote: > > Am Montag, dem 28.07.2025 um 11:18 -0700 schrieb Yeoul Na: >> >> >>> On Jul 28, 2025, at 10:27 AM, Qing Zhao <qing.z...@oracle.com> wrote: >>> >>> >>> >>>> On Jul 26, 2025, at 12:43, Yeoul Na <yeoul...@apple.com> wrote: >>>> >>>> >>>> >>>>> On Jul 24, 2025, at 3:52 PM, Kees Cook <k...@kernel.org> wrote: >>>>> >>>>> On Thu, Jul 24, 2025 at 04:26:12PM +0000, Aaron Ballman wrote: >>>>>> Ah, apologies, I wasn't clear. My thinking is: we're (Clang folks) >>>>>> going to want it to work in C++ mode because of shared headers. If it >>>>>> works in C++ mode, then we have to figure out what it means with all >>>>>> the various C++ features that are possible, not just the use cases >>>>> >>>>> I am most familiar with C, so I may be missing something here, but if >>>>> -fbounds-safety is intended to be C only, then why not just make it >>>>> unrecognized in C++? >>>> >>>> The bounds safety annotations must also be parsable in C++. While C++ can >>>> get bounds checking by using std::span instead of raw pointers, switching >>>> to std::span breaks ABI. Therefore, >>>> in many situations, C++ code must continue to use raw pointers—for >>>> example, when interoperating with C code by sharing headers with C. In >>>> such cases, bounds annotations can help close >>>> safety gaps in raw pointers. >>> >>> -fbound-safety feature was initially proposed as an C extension, So, it’s >>> natural to make it compatible with C language, not C++. >>> If C++ also need such a feature, then an extension to C++ is needed too. >>> If a consistent syntax for this feature can satisfy both C and C++, that >>> will be ideal. >>> However, if providing such consistent syntax requires major changes to C >>> language, >>> ( a new name lookup scope, and late parsing), it might be a good idea to >>> provide different syntax for C and C++. >> >> >> So the main problem here is when the "same code” will be parsed in both in C >> and C++, which is quite common in practice. >> >> Therefore, we need a way to reasonably write code that works both C and C++. >> >> From my perspective, that means: >> >> 1. The same spelling doesn’t “silently" behave differently in C and C++. >> 2. At least the most common use cases (i.e., __counted_by(peer)) should be >> able to be written the same way in C and C++, without ceremony. >> >> Here is our compromise proposal that meets these requirements, until we get >> blessing from the standard for a more elegant solution: >> >> 1. `__counted_by(member)` keeps working as is: late parsing + name lookup >> finds the member name first >> 2. `__counted_by_expr(expr)` uses a new syntax (e.g., __self), and is not >> allowed to use a name that matches the member name without the new syntax >> even if that would’ve resolved to a >> global variable. Use something like `__global_ref(id)` to disambiguate. >> This rule will prevent the confusion where `__counted_by_expr(id)` and >> `__counted_by(id)` may designate different >> entities. >> >> Here are the examples: >> >> Ex 1) >> constexpr int n = 10; >> >> struct s { >> int *__counted_by(n) ptr; // resolves to member `n`; which matches the >> current behavior >> int n; >> }; >> >> Ex 2) >> constexpr int n = 10; >> struct s { >> int *__counted_by_expr(n) ptr; // error: referring to a member name >> without “__self." >> int n; >> }; >> >> Ex 3) >> constexpr int n = 10; >> struct s { >> int *__counted_by_expr(__self.n) ptr; // resolves to member `n` >> int n; >> }; >> >> >> Ex 4) >> constexpr int n = 10; >> struct s { >> int *__counted_by_expr(__self.n + 1) ptr; // resolves to member `n` >> int n; >> }; >> >> >> Ex 5) >> constexpr int n = 10; >> struct s { >> int *__counted_by_expr(__global_ref(n) + 1) ptr; // resolves to global `n` >> int n; >> }; >> >> >> Ex 6) >> constexpr int n = 10; >> struct s { >> int *__counted_by_expr(n + 1) ptr; // resolves to global `n`; okay, no >> matching member name >> }; >> >> Or in case, people prefer forward declaration inside `__counted_by_expr()`, >> the similar rule can apply to achieve the same goal. >> > > Thank you Yeoul! > > I think it is a reasonable compromise.
Yes, I agree. -:) It adds two new keywords in both C and C++ (__self and __global_ref) to explicitly mark the scopes for the variables inside the attribute. will definitely resolve the lookup scope ambiguity issue in both C and C++. However, it will not resolve the issue when the counted_by field is declared After the pointer field. So, forward declarations is still needed to resolve this issue, I think. Qing > I guess a proposal is ready > when nobody likes it but everybody can live with it. Hopefully > we can agree on something nicer later. > > > Martin > > > >> Yeoul >> >>> >>> Qing >>>> >>>> Yeoul >>>> >>>> >>>>> Shared headers don't seem like much of a challenge; >>>>> e.g. Linux uses macros specifically to avoid mixing illegal syntax into >>>>> places where it isn't supported. For example, why can't Clang have: >>>>> >>>>> #if defined(__cplusplus) >>>>> # define __counted_by(ARGS...) >>>>> #else >>>>> # define __counted_by(ARGS...) __attribute__((counted_by(ARGS))) >>>>> #endif >>>>> >>>>> And then use __counted_by() in all the shared headers? C++ uses will >>>>> ignore it, and C uses will apply the attributes. >>>>> >>>>> It seems weird to me that Clang needs to solve how -fbounds-safety works >>>>> with C++ if it's not for _use_ in C++. I feel like I'm missing something >>>>> about features that can't be macro-ified or some ABI issue, but I keep >>>>> coming up empty. >>>>> >>>>> -- >>>>> Kees Cook >> >