https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108896
--- Comment #20 from Martin Uecker <muecker at gwdg dot de> --- Am Montag, dem 06.03.2023 um 19:15 +0000 schrieb isanbard at gmail dot com: > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108896 > > --- Comment #18 from Bill Wendling <isanbard at gmail dot com> --- > (In reply to Martin Uecker from comment #17) > > Am Freitag, dem 03.03.2023 um 23:18 +0000 schrieb isanbard at gmail dot com: > > ... > > > But even we make it resolve the name, which we > > have to do for all proposals, it is something different. > > > > If offsetof it would resolve the count of a different > > struct of the same *type* (here a non-existent one at > > address zero). Here we need a self reference to the > > same *object*. > > > If we make it an attribute, we have more control over what the arguments mean, > what they refer to, etc. > > For the record, I'm not opposed to the idea of using the designated > initializer > syntax. I just think it's good to explore other ideas before settling on > extending C (which is a bit heavy-handed). I agree. An attribute is simple and extending C will take more care (and work). The reason I think we should also extend C (together with WG14) is because this would allow writing code where the bound is never lost because it is encoded in the type, while the __builtin_dynamic_object_size is extremely useful to enhance existing code bases, but is best effort only. So I think we should do both. ... > > > > > > It also has the benefit of > > > > > allowing one to reference a variable not in the structure: > > > > > > > > > > const int items; > > > > > struct object { > > > > > ... > > > > > char items; > > > > > ... > > > > > struct inner { > > > > > ... > > > > > int flex[] __attribute__((__element_count__(items))); /* > > > > > References > > > > > global "items" */ > > > > > }; > > > > > } *ptr; > > > > > > > > Whether you allow this or not has nothing to do with the syntax. > > > > > > > > The question is what semantics you attach to this and this is > > > > also a question in your example. > > > > > > > > If you define > > > > > > > > struct inner* a = ... > > > > > > > > What does it say for a->flex ? > > > > > > > I need to point out that I used "offsetof" only as an example. It's > > > possible to > > > create something more robust which will carry along type information, > > > etc., > > > which the current offsetof macro throws away. I should have made that > > > clear. > > > > > > The sanitizers that see "a->flex" will try to find the correct variable. > > > If > > > they can't, then they won't generate a check. In the case of it > > > referencing a > > > non-field member, it'll use that if it's within scope. If it refers to a > > > field > > > member of a parent container that's not within scope, it'll also not > > > generate a > > > check. It's unfortunate that these checks are done as a "best effort," > > > but it > > > could lead to software changes to improve security checks (like passing a > > > parent structure into a function rather than an inner structure. > > > > Yes. We could also have an optional warning which warns about accessing > > 'flex' in a context where 'items' is not accessible. My point is that > > this feature of potentially referring to stuff which may not be accessible > > in all cases makes implementation more complicated. > > > It does make it more complicated, that's true. > > I haven't seen comments on Kees's first example, where "malloc" returns an > "__alloc_size" hint that's lost when "p" is returned from the function (at > least in Clang). If that information is kept around, it would expand the > number > of bounds checks we could perform. (Kudos if this is currently the case in > GCC.) I think not. But this would not work across TU boundaries anyway. https://godbolt.org/z/eW9GT579r Martin