Al Viro wrote: > We have a fun problem and for a change it's not sparse fault. > It's gcc folks' one. Basically, __attribute__((...)) behaves in > an idiotic way and it's an intentional (and documented) behaviour. > In declaration of form > T __attribute__((foo)) **v; > the attribute applies to v, not to **v. IOW, in that position it > behaves (regardless of the nature of attribute) as storage class, > not as a qualifier. Even if the same attribute can be used in > T * __attribute__((foo)) *v; > where it will apply to *v. Intended way to have it apply to **v is > T (__attribute__((foo)) **v); > > To put it mildly, that blows. Note that qualifiers can *not* behave > that way - direct declarator can not expand to (<qualifier> <something>). > I.e. if you replace __attribute__((foo)) with qualifier in the > above, you'll get invalid syntax. Wow. Insane. So these all declare the same type: __attribute__((foo)) T *v; T __attribute__((foo)) *v; T *__attribute__((foo)) v; ? Specifically, they point to a foo-T, for convenient shooting? > Now, that idiocy would be none of our concern, if not for the fact > that noderef and address_space() are definitely supposed to imitate > qualifiers. context also represents a qualifier; the position of the qualifier should determine things like whether you want to enforce the context when you access a pointer or dereference a pointer. > If anybody seriously suggests switching to syntax > like > int (__user *p); > all over the place, well... Definitely not an option. > Note that gcc rules for __attribute__() (and that's the only source > of rules we _have_ for the damn thing) clearly say that > int __user *p; > is the same thing as > int *__user p; > > Now, we could declare gcc people responsible for that turd rejects > of Vogon Construction Fleet and handle the damn thing sanely. > The first part is clearly the right thing to do, but the second one... > Can't do without breaking gccisms using __attribute__. E.g. > int (__attribute__((mode(__pointer__))) *p); > is a gcc way to say "pointer to integer type equivalent to intptr_t" and > int __attribute__((mode(__pointer__))) *p; > is exactly the same thing as > int *p; > since the damn attribute applies to the entire type here (and is obviously > a no-op). > > Frankly, I would rather add a new primitive (__qualifier__) mirroring the > __attribute__, but acting like real qualifiers do. And switched the > noderef et.al. to it. Something like that sounds vaguely reasonable. It should allow the same set of attributes, and just change what they apply to. To use your example, T __qualifier__((foo)) *v; and T (__attribute__((foo)) *v); would mean the same thing. > The only real alternative is to have __attribute__ > behaviour dependent on its guts and that's not feasible - remember that > there can be more than one attribute in the list insider the damn thing. > Besides, it's bloody disgusting. Agreed. Not an option, even if we *could* implement it. - Josh Triplett
Attachment:
signature.asc
Description: OpenPGP digital signature