-
Notifications
You must be signed in to change notification settings - Fork 12.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Make naked functions incompatible with certain attributes #93809
Conversation
Some changes occurred in diagnostic error codes |
r? @jackh726 (rust-highfive has picked a reviewer for you, use r? to override) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Error explanations look good for me (they don't need a "fixed" example in this case considering how simple they are). Please wait for approval from someone on the compiler team before r+.
@GuillaumeGomez thanks, these were so simple that I wasn't even sure if they deserved their own extended explanations. Is it policy that every error should ideally have its own extended explanation someday? If not, what's the cutoff point for when not to make an extended explanation? |
If there is an error with an error code, then it should have an explanation (easy to remember 😆). There is a tracking issue for this as well but it might need to be updated (new error codes have been added I suppose). |
This comment has been minimized.
This comment has been minimized.
@GuillaumeGomez right, but I have the same problem when deciding if an error is too simple to deserve its own error code. :P Also, I could use your advice in resolving the build failure. The problem is the doctest for one of the extended descriptions:
The problem is that I'm using |
Would it better to have a single error code for invalid attribute mixing? (Or maybe just X + naked?) |
I could imagine in the future more attributes falling into this category. |
Possibly, I'm open to suggestions as to what is most appropriate here. Alternatively we could have just two error codes, one for codegen attributes + naked and one for testing attributes + naked. |
Thinking about it, I like the idea of consolidating these error codes into just "codegen attributes + naked" and "testing attributes + naked". As a bonus, we can avoid having an explicit example for target_feature, which sidesteps the need to bend over backwards to make this doctest platform-specific. |
This comment has been minimized.
This comment has been minimized.
You can use |
Currently #[inline] and #[track_caller] are incompatible with #[naked], and there are more such attributes on the way. In preparation for this, consolidate the existing checks into a central location so that they can all be handled together. In addition, clean up the wording of the existing error messages.
Per the comment at rust-lang#90957 (comment) make these two attributes incompatible out of an abundance of caution. This may be allowed in the future.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
@bstrie Would it be better to have an allow list for acceptable naked functions attributes? This would deny all new attributes without any manual intervention. |
Per the comment at rust-lang#90957 (comment) , this prevents #[naked] from being used with #[test], #[should_panic], #[ignore], and #[bench]. This also fixes an oversight where the #[naked]-related lint "undefined_naked_function_abi" was not being properly registered; it is now possible to allow/deny it as per usual.
I think that would be an unnecessary maintenance burden. IMO, when a feature is stabilized, it is the responsibility of the people behind that feature to ensure that it works with all existing language features. Thus, with naked functions it is our responsibility to ensure that it works correctly with all existing attributes, and to prevent it from being used with any attributes that it is incompatible with. Then, once naked functions are stabilized, it is the responsibility of future language features (e.g. new attributes) to ensure that they work correctly with all existing language features, which will include naked functions. Unless someone wants to argue why naked functions represent some greater risk than usual, I consider it outside the scope of this stabilization effort to try to pre-emptively prevent problems that may possibly arise from interactions with an unknowable list of future features. |
I still am not sure if it makes sense to have two separate errors (codegen + testing). And even, if it's worth having a single error code for all "invalid attribute combinations". I think I'd feel more comfortable looping in either @rust-lang/wg-diagnostics or @rust-lang/compiler for thoughts. |
How do we know that new feature authors have done this due diligence regarding naked functions? They add their new feature to the allow list with appropriate test coverage. All new features would be opt-in. So at least we wouldn't break existing code. However, where people do opt in, the failures can be subtle and hard to debug. Even worse, they might not fail but instead silently succeed with security implications (i.e. the stack is corrupted). I'm on the fence on an allowlist, but leaning towards pro. |
To ease any decision regarding error codes, here's a summary of the situation:
|
It is assumed that the lang team will hold feature authors to this standard before allowing a feature to be stabilized. It's not impossible for things to slip through--accidents happen--but this is the acceptable risk that comes with stabilizing any feature.
The threat in question involves a future attribute Meanwhile, the cost is very large. I find it eminently reasonable to assume that a feature author that adds an attribute that affects codegen will perform their due diligence in remembering to deny its use on |
I agree up until this point.
This is a very bad assumption. All users are impacted by these problems regardless if they are security-minded or not. And the interactions between these attributes are non-obvious.
Given that the number of users that consumes Rust features is exponentially larger than the number of Rust feature developers, the total cost is significantly smaller to the first group than to the second.
I would hope so indeed. But when this fails, it fails spectacularly. Trying to bisect this will be very painful. OTOH, being able to do a
This is because for other features that are this dangerous, like
But... doing this is safe. And fixing the oversight is trivial if there are no safety concerns. If you stabilize your feature and realize you've forgotten to add it to the allowlist, this should be a trivial patch that can be merged within the next release window. It isn't like you have to go back to the drawing board. It seems to me like you're arguing that it is reasonable to expect feature developers to remember to consider all the subtle interactions between codegen attributes but not reasonable to expect the same feature developers to remember to add one item to an allowlist. The former is far more work than the latter.
It seems to me like you're optimizing for the burden of the feature authors rather than for the safety of the consumers of this feature. |
Certainly, which is part of the problem with concerning ourselves with general hypotheticals. It would be easier to discuss the likely threat of this scenario if we had a more concrete example.
As mentioned, users looking to use attributes on their naked functions would also be bearing this cost. This is especially true for users of custom proc macros, since Rust cannot add external proc macros to the allowlist.
Rather, Rust's orthogonality usually allows feature developers to ignore most of Rust's features when implementing new features. The only existing features that need to be considered are those that have some likely overlap with the new feature; this quality makes new feature development much more tractable than it would be otherwise. This is why I suggest that it is likely that the author of a new codegen attribute (which will plausibly interact poorly with
I suspect that we may have gotten sidetracked with the safety argument here. The reason that the attributes in this PR are being made incompatible with Despite the amount of spilled ink here, I actually don't care all that much which approach is taken. My primary concern is with getting naked functions stabilized ASAP, and for the immediate future the allowlist approach and the blocklist approach will be semantically identical, and there's nothing stopping a future version of Rust from switching from one to the other. For maximum expediency, I will bring up to the lang team and implement whichever they currently think is the best approach. |
Custom proc macro attributes are all expanded (and removed) early in compilation. The only attributes remaining after macro expansion are built-in attributes, so the allowlist would only need to consider built-in attributes |
I was reading the back and forth, @npmccallum and @bstrie, but I'm feeling a bit lost. @npmccallum, are you arguing against an allow-list? Do you have an alternative proposal? |
@nikomatsakis , @npmccallum is arguing that the compiler should have a list of attributes that are allowed to be present on |
On Zulip Josh indicated a preference for an allowlist, so I'll make that change and push a new version of this PR. In the meantime I'll message the relevant groups on Zulip regarding the error code question so that we can keep moving there as well. |
I see. I think I am in favor of the "allow-list" approach that @npmccallum is advocating -- |
☔ The latest upstream changes (presumably #94121) made this pull request unmergeable. Please resolve the merge conflicts. |
Status:
|
@bstrie any updates on this? |
@Dylan-DPC yep, I have an update to this PR coming imminently. |
error[E0788]: cannot use testing attributes with `#[naked]` | ||
--> $DIR/naked-functions-testattrs.rs:12:1 | ||
| | ||
LL | #[naked] | ||
| ^^^^^^^^ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the output, can we also point with secondary spans to the other non applicable attributes?
error[E0736]: cannot use additional code generation attributes with `#[naked]` | ||
--> $DIR/naked-functions-target-feature.rs:21:1 | ||
| | ||
LL | #[target_feature(enable = "sse2")] | ||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we point at #[naked]
as well here, and maybe at the item name too?
…ssages, r=bjorn3 `#[naked]`: report incompatible attributes tracking issue: rust-lang#90957 this is a re-implementation of rust-lang#93809 by `@bstrie` which was closed 2 years ago due to inactivity. This PR takes some of the final comments into account, specifically providing a little more context in error messages, and using an allow list to determine which attributes are compatible with `#[naked]`. Notable attributes that are incompatible with `#[naked]` are: * `#[inline]` * `#[track_caller]` * ~~`#[target_feature]`~~ (this is now allowed, see discussion below) * `#[test]`, `#[ignore]`, `#[should_panic]` There may be valid use cases for `#[target_feature]` but for now it is disallowed. The others just directly conflict with what `#[naked]` should do. Naked functions are still important for systems programming, embedded and operating systems, so I'd like to move them forward.
…ssages, r=bjorn3 `#[naked]`: report incompatible attributes tracking issue: rust-lang#90957 this is a re-implementation of rust-lang#93809 by `@bstrie` which was closed 2 years ago due to inactivity. This PR takes some of the final comments into account, specifically providing a little more context in error messages, and using an allow list to determine which attributes are compatible with `#[naked]`. Notable attributes that are incompatible with `#[naked]` are: * `#[inline]` * `#[track_caller]` * ~~`#[target_feature]`~~ (this is now allowed, see PR discussion) * `#[test]`, `#[ignore]`, `#[should_panic]` These attributes just directly conflict with what `#[naked]` should do. Naked functions are still important for systems programming, embedded, and operating systems, so I'd like to move them forward.
…ssages, r=bjorn3 `#[naked]`: report incompatible attributes tracking issue: rust-lang#90957 this is a re-implementation of rust-lang#93809 by ``@bstrie`` which was closed 2 years ago due to inactivity. This PR takes some of the final comments into account, specifically providing a little more context in error messages, and using an allow list to determine which attributes are compatible with `#[naked]`. Notable attributes that are incompatible with `#[naked]` are: * `#[inline]` * `#[track_caller]` * ~~`#[target_feature]`~~ (this is now allowed, see PR discussion) * `#[test]`, `#[ignore]`, `#[should_panic]` These attributes just directly conflict with what `#[naked]` should do. Naked functions are still important for systems programming, embedded, and operating systems, so I'd like to move them forward.
Rollup merge of rust-lang#127853 - folkertdev:naked-function-error-messages, r=bjorn3 `#[naked]`: report incompatible attributes tracking issue: rust-lang#90957 this is a re-implementation of rust-lang#93809 by ``@bstrie`` which was closed 2 years ago due to inactivity. This PR takes some of the final comments into account, specifically providing a little more context in error messages, and using an allow list to determine which attributes are compatible with `#[naked]`. Notable attributes that are incompatible with `#[naked]` are: * `#[inline]` * `#[track_caller]` * ~~`#[target_feature]`~~ (this is now allowed, see PR discussion) * `#[test]`, `#[ignore]`, `#[should_panic]` These attributes just directly conflict with what `#[naked]` should do. Naked functions are still important for systems programming, embedded, and operating systems, so I'd like to move them forward.
See the comment thread beginning at #90957 (comment) for justification.
Commit breakdown:
Fix copy/paste errors in check_attr
Consolidate checking for attributes not compatible with #[naked]
Currently #[inline] and #[track_caller] are incompatible with #[naked], and there are more such attributes on the way.
In preparation for this, consolidate the existing checks into a central location so that they can all be handled together.
In addition, clean up the wording of the existing error messages.
Forbid #[target_feature] from being used on naked functions
Per the comment at Tracking Issue for RFC #2972: Constrained Naked Functions #90957 (comment) , make these two attributes incompatible out of an abundance of caution. This may be allowed in the future.
Forbid testing attributes from being used with #[naked]
Per the comment at Tracking Issue for RFC #2972: Constrained Naked Functions #90957 (comment) , this prevents #[naked] from being used with #[test], #[should_panic], #[ignore], and #[bench].
This also fixes an oversight where the #[naked]-related lint "undefined_naked_function_abi" was not being properly registered; it is now possible to allow/deny it as per usual.