summary refs log tree commit diff
path: root/compiler/rustc_session/src/session.rs
AgeCommit message (Collapse)AuthorLines
2022-06-16Rollup merge of #97757 - xFrednet:rfc-2383-expect-with-force-warn, ↵Matthias Krüger-0/+15
r=wesleywiser,flip1995 Support lint expectations for `--force-warn` lints (RFC 2383) Rustc has a `--force-warn` flag, which overrides lint level attributes and forces the diagnostics to always be warn. This means, that for lint expectations, the diagnostic can't be suppressed as usual. This also means that the expectation would not be fulfilled, even if a lint had been triggered in the expected scope. This PR now also tracks the expectation ID in the `ForceWarn` level. I've also made some minor adjustments, to possibly catch more bugs and make the whole implementation more robust. This will probably conflict with https://github.com/rust-lang/rust/pull/97718. That PR should ideally be reviewed and merged first. The conflict itself will be trivial to fix. --- r? `@wesleywiser` cc: `@flip1995` since you've helped with the initial review and also discussed this topic with me. :upside_down_face: Follow-up of: https://github.com/rust-lang/rust/pull/87835 Issue: https://github.com/rust-lang/rust/issues/85549 Yeah, and that's it.
2022-06-16Support lint expectations for `--force-warn` lints (RFC 2383)xFrednet-0/+15
2022-06-14Auto merge of #96285 - flip1995:pk-vfe, r=nagisabors-6/+6
Introduce `-Zvirtual-function-elimination` codegen flag Fixes #68262 This PR adds a codegen flag `-Zvirtual-function-elimination` to enable the VFE optimization in LLVM. To make this work, additonal information has to be added to vtables ([`!vcall_visibility` metadata](https://llvm.org/docs/TypeMetadata.html#vcall-visibility-metadata) and a `typeid` of the trait). Furthermore, instead of just `load`ing functions, the [`llvm.type.checked.load` intrinsic](https://llvm.org/docs/LangRef.html#llvm-type-checked-load-intrinsic) has to be used to map functions to vtables. For technical details of the changes, see the commit messages. I also tested this flag on https://github.com/tock/tock on different boards to verify that this fixes the issue https://github.com/tock/tock/issues/2594. This flag is able to improve the size of the resulting binary by about 8k-9k bytes by removing the unused debug print functions. [Rendered documentation update](https://github.com/flip1995/rust/blob/pk-vfe/src/doc/rustc/src/codegen-options/index.md#virtual-function-elimination)
2022-06-14Auto merge of #78781 - eddyb:measureme-rdpmc, r=oli-obkbors-1/+2
Integrate measureme's hardware performance counter support. *Note: this is a companion to https://github.com/rust-lang/measureme/pull/143, and duplicates some information with it for convenience* **(much later) EDIT**: take any numbers with a grain of salt, they may have changed since initial PR open. ## Credits I'd like to start by thanking `@alyssais,` `@cuviper,` `@edef1c,` `@glandium,` `@jix,` `@Mark-Simulacrum,` `@m-ou-se,` `@mystor,` `@nagisa,` `@puckipedia,` and `@yorickvP,` for all of their help with testing, and valuable insight and suggestions. Getting here wouldn't have been possible without you! (If I've forgotten anyone please let me know, I'm going off memory here, plus some discussion logs) ## Summary This PR adds support to `-Z self-profile` for counting hardware events such as "instructions retired" (as opposed to being limited to time measurements), using the `rdpmc` instruction on `x86_64` Linux. While other OSes may eventually be supported, preliminary research suggests some kind of kernel extension/driver is required to enable this, whereas on Linux any user can profile (at least) their own threads. Supporting Linux on architectures other than x86_64 should be much easier (provided the hardware supports such performance counters), and was mostly not done due to a lack of readily available test hardware. That said, 32-bit `x86` (aka `i686`) would be almost trivial to add and test once we land the initial `x86_64` version (as all the CPU detection code can be reused). A new flag `-Z self-profile-counter` was added, to control which of the named `measureme` counters is used, and which defaults to `wall-time`, in order to keep `-Z self-profile`'s current functionality unchanged (at least for now). The named counters so far are: * `wall-time`: the existing time measurement * name chosen for consistency with `perf.rust-lang.org` * continues to use `std::time::Instant` for a nanosecond-precision "monotonic clock" * `instructions:u`: the hardware performance counter usually referred to as "Instructions retired" * here "retired" (roughly) means "fully executed" * the `:u` suffix is from the Linux `perf` tool and indicates the counter only runs while userspace code is executing, and therefore counts no kernel instructions * *see [Caveats/Subtracting IRQs](https://hackmd.io/sH315lO2RuicY-SEt7ynGA?view#Subtracting-IRQs) for why this isn't entirely true and why `instructions-minus-irqs:u` should be preferred instead* * `instructions-minus-irqs:u`: same as `instructions:u`, except the count of hardware interrupts ("IRQs" here for brevity) is subtracted * *see [Caveats/Subtracting IRQs](https://hackmd.io/sH315lO2RuicY-SEt7ynGA?view#Subtracting-IRQs) for why this should be preferred over `instructions:u`* * `instructions-minus-r0420:u`: experimental counter, same as `instructions-minus-irqs:u` but subtracting an undocumented counter (`r0420:u`) instead of IRQs * the `rXXXX` notation is again from Linux `perf`, and indicates a "raw" counter, with a hex representation of the low-level counter configuration - this was picked because we still don't *really* know what it is * this only exists for (future) testing and isn't included/used in any comparisons/data we've put together so far * *see [Challenges/Zen's undocumented 420 counter](https://hackmd.io/sH315lO2RuicY-SEt7ynGA?view#Epilogue-Zen’s-undocumented-420-counter) for details on how this counter was found and what it does* --- There are also some additional commits: * ~~see [Challenges/Rebasing *shouldn't* affect the results, right?](https://hackmd.io/sH315lO2RuicY-SEt7ynGA?view#Rebasing-*shouldn’t*-affect-the-results,-right) for details on the changes to `rustc_parse` and `rustc_trait_section` (the latter far more dubious, and probably shouldn't be merged, or not as-is)~~ * **EDIT**: the effects of these are no long quantifiable, the PR includes reverts for them * ~~see [Challenges/`jemalloc`: purging will commence in ten seconds](https://hackmd.io/sH315lO2RuicY-SEt7ynGA?view#jemalloc-purging-will-commence-in-ten-seconds) for details on the `jemalloc` change~~ * this is also separately found in #77162, and we probably want to avoid doing it by default, ideally we'd use the runtime control API `jemalloc` offers (assuming that can stop the timer that's already running, which I'm not sure about) * **EDIT**: until we can do this based on `-Z` flags, this commit has also been reverted * the `proc_macro` change was to avoid randomized hashing and therefore ASLR-like effects --- **(much later) EDIT**: take any numbers with a grain of salt, they may have changed since initial PR open. #### Write-up / report Because of how extensive the full report ended up being, I've kept most of it [on `hackmd.io`](https://hackmd.io/sH315lO2RuicY-SEt7ynGA?view), but for convenient access, here are all the sections (with individual links): <sup>(someone suggested I'd make a backup, so [here it is on the wayback machine](http://web.archive.org/web/20201127164748/https://hackmd.io/sH315lO2RuicY-SEt7ynGA?view) - I'll need to remember to update that if I have to edit the write-up)</sup> * [**Motivation**](https://hackmd.io/sH315lO2RuicY-SEt7ynGA?view#Motivation) * [**Results**](https://hackmd.io/sH315lO2RuicY-SEt7ynGA?view#Results) * [**Overhead**](https://hackmd.io/sH315lO2RuicY-SEt7ynGA?view#Overhead) *Preview (see the report itself for more details):* |Counter|Total<br>`instructions-minus-irqs:u`|Overhead from "Baseline"<br>(for all 1903881<br>counter reads)|Overhead from "Baseline"<br>(per each counter read)| |-|-|-|-| |Baseline|63637621286 ±6|| |`instructions:u`|63658815885 ±2|&nbsp;&nbsp;+21194599 ±8|&nbsp;&nbsp;+11| |`instructions-minus-irqs:u`|63680307361 ±13|&nbsp;&nbsp;+42686075 ±19|&nbsp;&nbsp;+22| |`wall-time`|63951958376 ±10275|+314337090 ±10281|+165| * [**"Macro" noise (self time)**](https://hackmd.io/sH315lO2RuicY-SEt7ynGA?view#“Macro”-noise-(self-time)) *Preview (see the report itself for more details):* || `wall-time` (ns) | `instructions:u` | `instructions-minus-irqs:u` -: | -: | -: | -: `typeck` | 5478261360 ±283933373 (±~5.2%) | 17350144522 ±6392 (±~0.00004%) | 17351035832.5 ±4.5 (±~0.00000003%) `expand_crate` | 2342096719 ±110465856 (±~4.7%) | 8263777916 ±2937 (±~0.00004%) | 8263708389 ±0 (±~0%) `mir_borrowck` | 2216149671 ±119458444 (±~5.4%) | 8340920100 ±2794 (±~0.00003%) | 8341613983.5 ±2.5 (±~0.00000003%) `mir_built` | 1269059734 ±91514604 (±~7.2%) | 4454959122 ±1618 (±~0.00004%) | 4455303811 ±1 (±~0.00000002%) `resolve_crate` | 942154987.5 ±53068423.5 (±~5.6%) | 3951197709 ±39 (±~0.000001%) | 3951196865 ±0 (±~0%) * [**"Micro" noise (individual sampling intervals)**](https://hackmd.io/sH315lO2RuicY-SEt7ynGA?view#“Micro”-noise-(individual-sampling-intervals)) * [**Caveats**](https://hackmd.io/sH315lO2RuicY-SEt7ynGA?view#Caveats) * [**Disabling ASLR**](https://hackmd.io/sH315lO2RuicY-SEt7ynGA?view#Disabling-ASLR) * [**Non-deterministic proc macros**](https://hackmd.io/sH315lO2RuicY-SEt7ynGA?view#Non-deterministic-proc-macros) * [**Subtracting IRQs**](https://hackmd.io/sH315lO2RuicY-SEt7ynGA?view#Subtracting-IRQs) * [**Lack of support for multiple threads**](https://hackmd.io/sH315lO2RuicY-SEt7ynGA?view#Lack-of-support-for-multiple-threads) * [**Challenges**](https://hackmd.io/sH315lO2RuicY-SEt7ynGA?view#Challenges) * [**How do we even read hardware performance counters?**](https://hackmd.io/sH315lO2RuicY-SEt7ynGA?view#How-do-we-even-read-hardware-performance-counters) * [**ASLR: it's free entropy**](https://hackmd.io/sH315lO2RuicY-SEt7ynGA?view#ASLR-it’s-free-entropy) * [**The serializing instruction**](https://hackmd.io/sH315lO2RuicY-SEt7ynGA?view#The-serializing-instruction) * [**Getting constantly interrupted**](https://hackmd.io/sH315lO2RuicY-SEt7ynGA?view#Getting-constantly-interrupted) * [**AMD patented time-travel and dubbed it `SpecLockMap`<br><sup>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;or: "how we accidentally unlocked `rr` on AMD Zen"</sup>**](https://hackmd.io/sH315lO2RuicY-SEt7ynGA?view#AMD-patented-time-travel-and-dubbed-it-SpecLockMapnbspnbspnbspnbspnbspnbspnbspnbspor-“how-we-accidentally-unlocked-rr-on-AMD-Zen”) * [**`jemalloc`: purging will commence in ten seconds**](https://hackmd.io/sH315lO2RuicY-SEt7ynGA?view#jemalloc-purging-will-commence-in-ten-seconds) * [**Rebasing *shouldn't* affect the results, right?**](https://hackmd.io/sH315lO2RuicY-SEt7ynGA?view#Rebasing-*shouldn’t*-affect-the-results,-right) * [**Epilogue: Zen's undocumented 420 counter**](https://hackmd.io/sH315lO2RuicY-SEt7ynGA?view#Epilogue-Zen’s-undocumented-420-counter)
2022-06-14Add -Zvirtual-function-elimination flagflip1995-6/+6
Adds the virtual-function-elimination unstable compiler flag and a check that this flag is only used in combination with -Clto. LLVM can only apply this optimization with fat LTO.
2022-06-13Integrate measureme's hardware performance counter support.Eduard-Mihai Burtescu-1/+2
2022-06-10lint: add diagnostic translation migration lintsDavid Wood-0/+1
Introduce allow-by-default lints for checking whether diagnostics are written in `SessionDiagnostic`/`AddSubdiagnostic` impls and whether diagnostics are translatable. These lints can be denied for modules once they are fully migrated to impls and translation. Signed-off-by: David Wood <david.wood@huawei.com>
2022-05-06sess: add `create_{err,warning}`David Wood-0/+12
Currently, the only API for creating errors from a diagnostic derive will emit it immediately. This makes it difficult to add subdiagnostics to diagnostics from the derive, so add `create_{err,warning}` functions that return the diagnostic without emitting it. Signed-off-by: David Wood <david.wood@huawei.com>
2022-04-25fix formattingChristian Poveda-5/+1
2022-04-25use `ParseSess` instead of `Session` in `into_diagnostic`Christian Poveda-5/+9
2022-04-15Rollup merge of #96026 - matthiaskrgr:clippy_compl_1304, r=Dylan-DPCDylan DPC-1/+1
couple of clippy::complexity fixes
2022-04-15Rollup merge of #94461 - jhpratt:2024-edition, r=pnkfelixDylan DPC-0/+5
Create (unstable) 2024 edition [On Zulip](https://rust-lang.zulipchat.com/#narrow/stream/213817-t-lang/topic/Deprecating.20macro.20scoping.20shenanigans/near/272860652), there was a small aside regarding creating the 2024 edition now as opposed to later. There was a reasonable amount of support and no stated opposition. This change creates the 2024 edition in the compiler and creates a prelude for the 2024 edition. There is no current difference between the 2021 and 2024 editions. Cargo and other tools will need to be updated separately, as it's not in the same repository. This change permits the vast majority of work towards the next edition to proceed _now_ instead of waiting until 2024. For sanity purposes, I've merged the "hello" UI tests into a single file with multiple revisions. Otherwise we'd end up with a file per edition, despite them being essentially identical. ````@rustbot```` label +T-lang +S-waiting-on-review Not sure on the relevant team, to be honest.
2022-04-13couple of clippy::complexity fixesMatthias Krüger-1/+1
2022-04-13errors: lazily load fallback fluent bundleDavid Wood-15/+7
Loading the fallback bundle in compilation sessions that won't go on to emit any errors unnecessarily degrades compile time performance, so lazily create the Fluent bundle when it is first required. Signed-off-by: David Wood <david.wood@huawei.com>
2022-04-12sess: try sysroot candidates for fluent bundleDavid Wood-11/+13
Instead of checking only the user provided sysroot or the default (when no sysroot is provided), search user provided sysroot and then check default sysroots for locale requested by the user. Signed-off-by: David Wood <david.wood@huawei.com>
2022-04-05session: opt for enabling directionality markersDavid Wood-2/+6
Add an option for enabling and disabling Fluent's directionality isolation markers in output. Disabled by default as these can render in some terminals and applications. Signed-off-by: David Wood <david.wood@huawei.com>
2022-04-05macros: translatable struct attrs and warningsDavid Wood-3/+13
Signed-off-by: David Wood <david.wood@huawei.com>
2022-04-05errors: implement sysroot/testing bundle loadingDavid Wood-6/+19
Extend loading of Fluent bundles so that bundles can be loaded from the sysroot based on the language requested by the user, or using a nightly flag. Sysroot bundles are loaded from `$sysroot/share/locale/$locale/*.ftl`. Signed-off-by: David Wood <david.wood@huawei.com>
2022-04-05errors: implement fallback diagnostic translationDavid Wood-35/+92
This commit updates the signatures of all diagnostic functions to accept types that can be converted into a `DiagnosticMessage`. This enables existing diagnostic calls to continue to work as before and Fluent identifiers to be provided. The `SessionDiagnostic` derive just generates normal diagnostic calls, so these APIs had to be modified to accept Fluent identifiers. In addition, loading of the "fallback" Fluent bundle, which contains the built-in English messages, has been implemented. Each diagnostic now has "arguments" which correspond to variables in the Fluent messages (necessary to render a Fluent message) but no API for adding arguments has been added yet. Therefore, diagnostics (that do not require interpolation) can be converted to use Fluent identifiers and will be output as before.
2022-04-05span: move `MultiSpan`David Wood-2/+2
`MultiSpan` contains labels, which are more complicated with the introduction of diagnostic translation and will use types from `rustc_errors` - however, `rustc_errors` depends on `rustc_span` so `rustc_span` cannot use types like `DiagnosticMessage` without dependency cycles. Introduce a new `rustc_error_messages` crate that can contain `DiagnosticMessage` and `MultiSpan`. Signed-off-by: David Wood <david.wood@huawei.com>
2022-04-02Create 2024 editionJacob Pratt-0/+5
2022-03-27Make fatal DiagnosticBuilder yield neverMichael Goulet-20/+11
2022-03-26Auto merge of #95296 - workingjubilee:pretty-session, r=Dylan-DPCbors-6/+6
Prettify rustc_session with recent conveniences No functional changes. I felt like making something beautiful.
2022-03-24Prettify rustc_session fmt with capturing args (nfc)Jubilee Young-6/+6
2022-03-20Filter OnceNote in diagnostic infra.Camille GILLOT-73/+1
2022-03-16rustc_error: make ErrorReported impossible to constructmark-17/+28
There are a few places were we have to construct it, though, and a few places that are more invasive to change. To do this, we create a constructor with a long obvious name.
2022-03-03Auto merge of #87835 - xFrednet:rfc-2383-expect-attribute-with-ids, ↵bors-0/+7
r=wesleywiser Implementation of the `expect` attribute (RFC 2383) This is an implementation of the `expect` attribute as described in [RFC-2383](https://rust-lang.github.io/rfcs/2383-lint-reasons.html). The attribute allows the suppression of lint message by expecting them. Unfulfilled lint expectations (meaning no expected lint was caught) will emit the `unfulfilled_lint_expectations` lint at the `expect` attribute. ### Example #### input ```rs // required feature flag #![feature(lint_reasons)] #[expect(unused_mut)] // Will warn about an unfulfilled expectation #[expect(unused_variables)] // Will be fulfilled by x fn main() { let x = 0; } ``` #### output ```txt warning: this lint expectation is unfulfilled --> $DIR/trigger_lint.rs:3:1 | LL | #[expect(unused_mut)] // Will warn about an unfulfilled expectation | ^^^^^^^^^^ | = note: `#[warn(unfulfilled_lint_expectations)]` on by default ``` ### Implementation This implementation introduces `Expect` as a new lint level for diagnostics, which have been expected. All lint expectations marked via the `expect` attribute are collected in the [`LintLevelsBuilder`] and assigned an ID that is stored in the new lint level. The `LintLevelsBuilder` stores all found expectations and the data needed to emit the `unfulfilled_lint_expectations` in the [`LintLevelsMap`] which is the result of the [`lint_levels()`] query. The [`rustc_errors::HandlerInner`] is the central error handler in rustc and handles the emission of all diagnostics. Lint message with the level `Expect` are suppressed during this emission, while the expectation ID is stored in a set which marks them as fulfilled. The last step is then so simply check if all expectations collected by the [`LintLevelsBuilder`] in the [`LintLevelsMap`] have been marked as fulfilled in the [`rustc_errors::HandlerInner`]. Otherwise, a new lint message will be emitted. The implementation of the `LintExpectationId` required some special handling to make it stable between sessions. Lints can be emitted during [`EarlyLintPass`]es. At this stage, it's not possible to create a stable identifier. The level instead stores an unstable identifier, which is later converted to a stable `LintExpectationId`. ### Followup TO-DOs All open TO-DOs have been marked with `FIXME` comments in the code. This is the combined list of them: * [ ] The current implementation doesn't cover cases where the `unfulfilled_lint_expectations` lint is actually expected by another `expect` attribute. * This should be easily possible, but I wanted to get some feedback before putting more work into this. * This could also be done in a new PR to not add to much more code to this one * [ ] Update unstable documentation to reflect this change. * [ ] Update unstable expectation ids in [`HandlerInner::stashed_diagnostics`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_errors/struct.HandlerInner.html#structfield.stashed_diagnostics) ### Open questions I also have a few open questions where I would like to get feedback on: 1. The RFC discussion included a suggestion to change the `expect` attribute to something else. (Initiated by `@Ixrec` [here](https://github.com/rust-lang/rfcs/pull/2383#issuecomment-378424091), suggestion from `@scottmcm` to use `#[should_lint(...)]` [here](https://github.com/rust-lang/rfcs/pull/2383#issuecomment-378648877)). No real conclusion was drawn on that point from my understanding. Is this still open for discussion, or was this discarded with the merge of the RFC? 2. How should the expect attribute deal with the new `force-warn` lint level? --- This approach was inspired by a discussion with `@LeSeulArtichaut.` RFC tracking issue: #54503 Mentoring/Implementation issue: #85549 [`LintLevelsBuilder`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint/levels/struct.LintLevelsBuilder.html [`LintLevelsMap`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/lint/struct.LintLevelMap.html [`lint_levels()`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/context/struct.TyCtxt.html#method.lint_levels [`rustc_errors::HandlerInner`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_errors/struct.HandlerInner.html [`EarlyLintPass`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint/trait.EarlyLintPass.html
2022-03-02Set `LintExpectationId` in level and collect fulfilled ones (RFC-2383)xFrednet-1/+5
* Collect lint expectations and set expectation ID in level (RFC-2383) * Collect IDs of fulfilled lint expectations from diagnostics (RFC 2383)
2022-03-02Added `Expect` lint level and attribute (RFC-2383)xFrednet-0/+3
* Also added the `LintExpectationId` which will be used in future commits
2022-03-02rename ErrorReported -> ErrorGuaranteedmark-14/+14
2022-02-23rustc_errors: let `DiagnosticBuilder::emit` return a "guarantee of emission".Eduard-Mihai Burtescu-15/+35
2022-02-23rustc_errors: handle `force_warn` only through `DiagnosticId::Lint`.Eduard-Mihai Burtescu-10/+0
2022-02-23Replace `&mut DiagnosticBuilder`, in signatures, with `&mut Diagnostic`.Eduard-Mihai Burtescu-20/+14
2022-01-23Remove DiagnosticBuilder.quietmark-4/+0
2021-12-05Auto merge of #91555 - matthiaskrgr:rollup-pq0iaq7, r=matthiaskrgrbors-1/+1
Rollup of 4 pull requests Successful merges: - #90529 (Skip reborrows in AbstractConstBuilder) - #91437 (Pretty print empty blocks as {}) - #91450 (Don't suggest types whose inner type is erroneous) - #91535 (Stabilize `-Z emit-future-incompat` as `--json future-incompat`) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2021-12-05Rollup merge of #91535 - Aaron1011:stabilize-future-incompat, r=nagisaMatthias Krüger-1/+1
Stabilize `-Z emit-future-incompat` as `--json future-incompat` The FCP was completed in https://github.com/rust-lang/rust/issues/71249
2021-12-05Auto merge of #88611 - m-ou-se:array-into-iter-new-deprecate, r=joshtriplettbors-3/+2
Deprecate array::IntoIter::new.
2021-12-04Stabilize `-Z emit-future-incompat` as `--json future-incompat`Aaron Hill-1/+1
2021-12-04Use IntoIterator for array impl everywhere.Mara Bos-3/+2
2021-12-02Move instrument coverage config getters to `Options`Dylan MacKenzie-6/+3
2021-12-02Move `mir_opt_level` getter into `Options`Dylan MacKenzie-4/+1
2021-11-24Remove `-Z force-overflow-checks`Noah Lev-5/+1
It was replaced several years ago by the stable option `-C overflow-checks`. The goal was to delete the `-Z` flag once users had migrated [1]. Now that it's been several years, it makes sense to delete the old flag. See also the discussion on Zulip [2]. [1]: https://github.com/rust-lang/rust/issues/33134#issuecomment-280484097 [2]: https://rust-lang.zulipchat.com/#narrow/stream/131828-t-compiler/topic/overflow.20checks/near/262497224
2021-11-22add rustc option for using LLVM stack smash protectionBenjamin A. Bjørnseth-1/+20
LLVM has built-in heuristics for adding stack canaries to functions. These heuristics can be selected with LLVM function attributes. This patch adds a rustc option `-Z stack-protector={none,basic,strong,all}` which controls the use of these attributes. This gives rustc the same stack smash protection support as clang offers through options `-fno-stack-protector`, `-fstack-protector`, `-fstack-protector-strong`, and `-fstack-protector-all`. The protection this can offer is demonstrated in test/ui/abi/stack-protector.rs. This fills a gap in the current list of rustc exploit mitigations (https://doc.rust-lang.org/rustc/exploit-mitigations.html), originally discussed in #15179. Stack smash protection adds runtime overhead and is therefore still off by default, but now users have the option to trade performance for security as they see fit. An example use case is adding Rust code in an existing C/C++ code base compiled with stack smash protection. Without the ability to add stack smash protection to the Rust code, the code base artifacts could be exploitable in ways not possible if the code base remained pure C/C++. Stack smash protection support is present in LLVM for almost all the current tier 1/tier 2 targets: see test/assembly/stack-protector/stack-protector-target-support.rs. The one exception is nvptx64-nvidia-cuda. This patch follows clang's example, and adds a warning message printed if stack smash protection is used with this target (see test/ui/stack-protector/warn-stack-protector-unsupported.rs). Support for tier 3 targets has not been checked. Since the heuristics are applied at the LLVM level, the heuristics are expected to add stack smash protection to a fraction of functions comparable to C/C++. Some experiments demonstrating how Rust code is affected by the different heuristics can be found in test/assembly/stack-protector/stack-protector-heuristics-effect.rs. There is potential for better heuristics using Rust-specific safety information. For example it might be reasonable to skip stack smash protection in functions which transitively only use safe Rust code, or which uses only a subset of functions the user declares safe (such as anything under `std.*`). Such alternative heuristics could be added at a later point. LLVM also offers a "safestack" sanitizer as an alternative way to guard against stack smashing (see #26612). This could possibly also be included as a stack-protection heuristic. An alternative is to add it as a sanitizer (#39699). This is what clang does: safestack is exposed with option `-fsanitize=safe-stack`. The options are only supported by the LLVM backend, but as with other codegen options it is visible in the main codegen option help menu. The heuristic names "basic", "strong", and "all" are hopefully sufficiently generic to be usable in other backends as well. Reviewed-by: Nikita Popov <nikic@php.net> Extra commits during review: - [address-review] make the stack-protector option unstable - [address-review] reduce detail level of stack-protector option help text - [address-review] correct grammar in comment - [address-review] use compiler flag to avoid merging functions in test - [address-review] specify min LLVM version in fortanix stack-protector test Only for Fortanix test, since this target specifically requests the `--x86-experimental-lvi-inline-asm-hardening` flag. - [address-review] specify required LLVM components in stack-protector tests - move stack protector option enum closer to other similar option enums - rustc_interface/tests: sort debug option list in tracking hash test - add an explicit `none` stack-protector option Revert "set LLVM requirements for all stack protector support test revisions" This reverts commit a49b74f92a4e7d701d6f6cf63d207a8aff2e0f68.
2021-11-08Don't proceed to codegen if there are lint errorsJoshua Nelson-1/+1
2021-10-25Add LLVM CFI support to the Rust compilerRamon de C Valle-0/+13
This commit adds LLVM Control Flow Integrity (CFI) support to the Rust compiler. It initially provides forward-edge control flow protection for Rust-compiled code only by aggregating function pointers in groups identified by their number of arguments. Forward-edge control flow protection for C or C++ and Rust -compiled code "mixed binaries" (i.e., for when C or C++ and Rust -compiled code share the same virtual address space) will be provided in later work as part of this project by defining and using compatible type identifiers (see Type metadata in the design document in the tracking issue #89653). LLVM CFI can be enabled with -Zsanitizer=cfi and requires LTO (i.e., -Clto).
2021-10-06Enable AutoFDO.Michael Benfield-0/+10
This largely involves implementing the options debug-info-for-profiling and profile-sample-use and forwarding them on to LLVM. AutoFDO can be used on x86-64 Linux like this: rustc -O -Cdebug-info-for-profiling main.rs -o main perf record -b ./main create_llvm_prof --binary=main --out=code.prof rustc -O -Cprofile-sample-use=code.prof main.rs -o main2 Now `main2` will have feedback directed optimization applied to it. The create_llvm_prof tool can be obtained from this github repository: https://github.com/google/autofdo Fixes #64892.
2021-10-03Practice diagnostic message conventionHirochika Matsumoto-1/+1
2021-10-01Rollup merge of #89322 - tmiasko:rm-optimization-fuel, r=michaelwoeristerManish Goregaokar-6/+1
Reapply "Remove optimization_fuel_crate from Session"
2021-09-28Reapply "Remove optimization_fuel_crate from Session"bjorn3-6/+1
2021-09-28rustc_session: Remove lint store from `Session`Vadim Petrochenkov-16/+1