AaronBallman wrote:

> I’m pretty sure our stance on this was that we very much _don’t_ want to 
> retain unrecognised attributes, but I don’t remember the exact reason. Iirc 
> @AaronBallman knows

I still have to give this more review, but this probably warrants an RFC. 
There's a *lot* of attributes in the wild we don't support and so I have no 
idea what this will do to memory overhead issues in Clang, particularly for 
attributes showing up in system headers.

There are two scenarios, both with different amounts of concern:

1) No idea about this attribute, never seen it before.
2) I know about this attribute, you're using it wrong (or on the wrong target, 
etc)

#2 is actually the significantly more problematic situation. We have a ton of 
code in the compiler that does things like `D->hasAttr<FooAttr>()` and presumes 
that if the semantic attribute is associated with the declaration, all is fine. 
We'd have to update *all* of those to do something more like `const auto *A = 
D->getAttr<FooAttr>(); A && A->isIgnoredButRetainedInTheAST()`, any uses 
through AST matchers would have to be updated, etc. So my stance is that we 
should never, ever support #2 by adding `FooAttr` into the AST, but it's fine 
to add an `UnknownAttr` into the AST in this case.

For both cases, I would expect we'd add some sort of `ThisIsntReallyAnAttrAttr` 
AST node which wraps the thing we want to ignore. There's still a problem that 
we need to audit everywhere we do `D->hasAttrs()` and presume that means there 
are attributes applied, but I think that's a much more tractable problem.

There are some open questions though:

* Is this going to retain attributes we know about but are used incorrectly? 
e.g., `int x [[gnu::packed]]`; if yes, will this also happen for things which 
are implemented as attributes but spelled another way? e.g., `alignas` or 
`constinit`?
* Are these to be treated as "real" attributes? e.g., if I write something on a 
primary template, does the instantiation get the unknown attribute as well? Are 
all unknown attributes on declarations inherited on redeclaration too?
* Is an unknown type attribute a real type attribute? e.g., `_Generic(int, int 
[[unknown]] : 1, int : 2, default : 0)` is this ambiguous because `int` is 
effectively specified twice or is this well-defined and returns `2`?
* What should happen for things like reflection? Does the declaration "have" 
the attribute if it's not one we support? 
* Does this include retaining invalid attributes? e.g., `[[12]]`
* I assume this also handles things like `[[using unknown: whatever]]`, but how 
much information do we want to retain about the form the user spelled in 
source? e.g., do we want to distinguish between that and 
`[[unknown::whatever]]`?


https://github.com/llvm/llvm-project/pull/209224
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to