https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59856
--- Comment #4 from Josh Triplett <josh at joshtriplett dot org> --- (In reply to Tom Tromey from comment #3) > (In reply to Josh Triplett from comment #2) > > > > The attribute syntax in the test case doesn't work with gcc. The > > > attributes > > > on the function definitions can't appear at the end. > > > > Placing attributes at the end of the function definition works with Sparse, > > and as far as I can tell with GCC as well. The Linux kernel uses trailing > > attributes on functions (both prototypes and definitions) fairly frequently, > > including with the context attribute. > > Experimentally it works with function declarations but not function > definitions. > There was some reason for this (ambiguity with K&R style?), but I forget > exactly. > > void declaration(void) __attribute__((const)); > > void definition(void) __attribute__((const)) > { > } > > pokyo. gcc --syntax-only q.c > q.c:3:1: error: attributes should be specified before the declarator in a > function definition > void definition(void) __attribute__((const)) > ^ OK, that explains a lot. The kernel extensively uses trailing attributes on declarations, but a more careful look shows that the *only* trailing attributes used in definitions appear via macros that only have non-empty definitions for Sparse. And Sparse parses those just fine. Unfortunate, and I'd love to see GCC handle trailing attributes (does a bug already exist for that somewhere?), but not something that should block *this* feature. (As a vaguely related aside, how does GCC disambiguate whether an attribute preceding the function declaration or definition applies to the return type or to the function? I really hope that doesn't depend on the specific attribute.) > > In general, it seems useful to have the ability to reference argument names > > in attributes on a function. For instance, imagine using argument names > > rather than indexes for the printf attribute or another attribute like it. > > Yeah, I agree. > > > The context attribute, though, wants something more complex than that: the > > ability to provide expressions based on those arguments, such as arg->lock. > > That does seem like a tall order. > > Ok, it wasn't clear to me exactly what the meaning of that argument was. > From the original text here it seemed like it would just be a plain name. > So, that's something to nail down. I looked at sparse's test suite but > it doesn't test this construct. Because Sparse doesn't actually do anything with that argument yet other than parse it. :) The theory was that Sparse would associate locks with actual objects, and match them up. (And/or feed that information into a runtime checker.) But since Sparse doesn't have the necessary semantic analysis to check if two expressions refer to the same object, and probably never will, that didn't happen. GCC, on the other hand, has alias analysis and similar. It doesn't seem too ridiculous for GCC to detect that arg->lock in two successive function calls refers to the same location. > > So I suspect it may make sense to run this after inlining, specialization, > > dead-code elimination, and similar. > > One difficulty in this case is choosing how to represent __context__. > My hack makes it a const function, and the value is never used, so gcc > is free to just drop all the calls to it. But the further back in > the pipeline the new pass is added, the harder it is to preserve this. > > It would be simpler for the plugin if __context__ were instead another > attribute on a different set of functions. I don't know how hard this > is on the kernel end though. Well, on the one hand, the compiler-specific header files could easily enough provide a different definition for Sparse and GCC. On the other hand, it seems unfortunate if the syntax doesn't actually match Sparse. On the third hand, very few users exist *outside* the kernel, and Sparse could potentially support a new syntax as well. Could you represent __context__ as a new GCC builtin? Would that make this any easier? Sparse actually tracks context as a property of basic blocks. > > I don't mind the use of Python, though I wonder how easily such a script > > could work by default. Given this script, how do you invoke GCC and run it? > > How much stability does this interface provide? Could the Linux kernel ship > > such a script and invoke it as part of the compile, given some dependency > > checks (and likely a Kconfig option if it increases build time > > significantly)? > > One nice thing about Python is that because it is so dynamic, it's reasonably > easy to make it adapt to different versions of gcc-python-plugin, if needed. > > Running it is easy. The "gcc-with-python2" wrapper script is just a > single line: > > ${CC:-gcc} -fplugin=python2 -fplugin-arg-python2-script=$@ > > So, it's really just adding a couple of options to the command line. > > It wouldn't be completely nuts to just put the whole gcc-python-plugin source > into the tree. It also wouldn't be too hard to just recode this plugin > in C++. I don't think it makes sense to put all of gcc-python-plugin into Linux. And from what I can tell, distribution packages typically ship this separately (if they ship it at all; AFAICT Debian only ships gcc-python3-plugin). So, I suspect the unfortunate answer is that Linux would probably want to ship the plugin as C/C++ and build it at build time if enabled. (Or we could integrate this functionality into GCC itself.) But despite that, Python seems like a great way to prototype it while we nail down the semantics more precisely.