On Mon, 11 Nov 2024, Alfie Richards wrote: > I see this code is very unclear in hindsight. The logic of this code > relies on that FMV functions are only allowed at file scope. > This should have a DECL_FILE_SCOPE_P check to avoid some of the ridiculous > cases you mentioned.
If you have an actual language rule that declarations of such functions are only permitted at file scope, that simplifies some things, but you need to consider cases such as: a function gets declared at block scope, then later turns out to be multiversioned with a declaration at file scope; does that render the previous declaration at block scope invalid? > In this way I suppose I'm sort of using the "shadows" structure to be a linked > list of my FMV bindings, to link them up and work out the different versions. The existing design expects a shadowed declaration to be in a different scope; not to possibly have multiple declarations of ordinary identifiers with the same name (different versions of a function) in the same scope. If you think that putting multiple declarations of ordinary identifiers with the same name in the same scope will work, you need to give a more detailed analysis of existing logic working with these structures (and explain why, when an identifier is looked up by name, the preferred variant - whatever that is - is the declaration that will be returned after your changes). > > So all effects of diagnose_mismatched_decls should apply between different > > versions. But only a subset of merge_decls is relevant (such as forming > > composite types) - and that subset would be relevant in both directions, > > because both declarations remain in use afterwards. Or if you don't want > > the complications there, you could define the semantics not to e.g. form > > composite types between different versions. > I don't follow what you mean that the logic of diagnose_mismatched_decls > should apply between versions? Shouldn't diagnose_mismatched_decls always > produce redefinition diagnostics in these cases as it isn't aware of FMV > attributes? Are you referring specifically to the logic for combining > signatures? I'm talking about logic for detecting ways in which declarations are incompatible, such as incompatible types. (Not about having multiple definitions of the same function, which I think is the main or only case that's meant to be allowed for multiversioned functions but not for others.) > - as much as possible I would like to stay as close to how the C++ > frontend handles this to avoid having to mess around with the hooks that The fundamental difference here is that the C++ language already supports multiple declarations of ordinary identifiers with the same name in the same scope (overloading etc.), whereas C doesn't. So you can't assume anything about data structures in the C++ front end for handling identifiers and scopes will reliably carry over to C; those in the C front end were never designed for the cases that C++ handles. (C *does* still have multiple kinds of identifiers that can appear with the same name in the same scope - for example, tags - but the expectation is still that there is only one ordinary identifier with a given name in a given scope.) -- Joseph S. Myers josmy...@redhat.com