On Mon, Jul 28, 2025 at 1:48 PM Qing Zhao <qing.z...@oracle.com> wrote:
> > 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.

This was suggested months ago, so sure, seems reasonable. How do we
handle function calls, like the "byte swap" example Kees pointed out?

> 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.

I suggest delayed parsing instead.

-bw

Reply via email to