This is a hard request to fulfil – this attribute requires access to the parameter list so it can name parameters, and the only syntactic place that’s allowed for [[]]
-style attributes is after the parameter list, which makes the attribute apply to the function type rather than declaration. It’s possible that this is actually the correct design (e.g., perhaps we want function pointer assignment to fail if the types aren’t similarly diagnosed) but this is also a pretty invasive approach in various ways – it would impact template specialization behavior, overloading, etc. Without WG21 or WG14 providing a way to write a function declaration attribute which can access the parameter list, I think we should continue to use __attribute__((diagnose_if))
with its current spelling.
Concretely, what I’m proposing is changing the current attribute from:
attr: diagnose_if ( expr , string-literal , string-literal )
which takes the condition to be tested, a string literal message to display to the user, and a string literal (enumerator) specifying warning vs error, into something more along these lines:
cat_enum : warning | error
category : string-literal | cat_enum
option_enum: ShowInSystemHeader | DefaultIgnore | DefaultError | SFINAEFailure
option-list: option_enum | option-list option
attr: diagnose_if ( expr , constant-expr , category ) |
diagnose_if ( expr , constant-expr , category , string-literal ) |
diagnose_if ( expr , constant-expr , category , string-literal , option-list )
which continues to take the condition to be tested, message to display to the user (now accepting any kind of C-string-producing constant expression), and category (spelled as either an enumerator or a string literal), but adds a string literal to specify the diagnostic group and a trailing list of enumeration options for the diagnostic. These trailing options are a subset of the ones we expose in our diagnostic .td files (and I’m not strongly tied to the spelling of the options so long as the enumerators are clearly named and documented).
I believe we can extend this interface in the future to cover other situations like diagnostic notes and diagnostic remarks, but those can be handled at a later date so we can focus on warnings and errors.
As a concrete example, this can be used like:
int isalpha(int ch)
__attribute__((diagnose_if(ch > (2 << sizeof(char) * (CHAR_BIT - 1)),
"can only pass 7-bit ASCII values",
warning, "conversion", DefaultError)));
which would produce a warning diagnostic under the -Wconversion
warning group which defaults to being an error whenever the function is passed a value that’s outside of the range of what ASCII encodes.
Some design considerations:
- The trailing options can be accepted in any order, which also allows us to extend that list in the future should we need to.
- I was thinking that the user can only specify existing warning groups. If they specify a warning group we do not support, I think the user should get an “unknown warning group” warning on the attribute, but the attribute otherwise continues to work, just issued under the generic warning group for
diagnose_if
. At some point in the future, we can consider extending the grammar to support InGroup ( string-literal )
as the warning group so the user can produce ad hoc groups, perhaps with an ability to optionally specify a parent diagnostic group.
- We would need to make sure that diagnostic suppression mechanisms work with the attribute (command line, pragmas, fatal error count cut-offs, etc).
- We may want to consider allowing users to pass in arguments to the diagnostic for diagnostic formatting similar to our C++ interface and uses of
%select
, etc, but for right now, I think accepting a constant expression is sufficient for configurability of the message itself.
- This currently only supports warning and error diagnostics, but we may want to someday extend this to allow users to emit notes; I’m not proposing that right now because notes are typically generated at other locations along with another diagnostic and we have no cross-language way to specify where to emit such notes from the context of the error|warning attribute.
Thank you for sharing that! There is overlap but I don’t think this proposal would meet our needs (as such, I do not support the WG21 proposal in its current form). Specifically, we need the ability to control things the standard traditionally won’t talk about, like diagnostic groups, diagnostic categories, and the various control knobs we need. Further, that proposal is entirely unusable in C. We should keep an eye on this in WG21, but I don’t think we need to follow that direction at this time.