about summary refs log tree commit diff
path: root/src
AgeCommit message (Collapse)AuthorLines
2021-11-22add rustc option for using LLVM stack smash protectionBenjamin A. Bjørnseth-0/+846
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-22Auto merge of #91099 - jsha:cleanup-undocumented, r=GuillaumeGomezbors-33/+4
Remove styles for details.undocumented The Rust code that generated tags with that class was deleted in 10bafe1975e53769180701508e2b8cd3a3b34a0e. r? `@GuillaumeGomez`
2021-11-22Auto merge of #90872 - ken-matsui:add-defer-to-rustdoc-template, r=jshabors-10/+10
Move `scripts` on the rustdoc template into `head` and apply the `defer` attribute Closes https://github.com/rust-lang/rust/issues/90719
2021-11-22Auto merge of #88681 - ehuss:duplicate-attributes, r=petrochenkovbors-122/+668
Check for duplicate attributes. This adds some checks for duplicate attributes. In many cases, the duplicates were being ignored without error or warning. This adds several kinds of checks (see `AttributeDuplicates` enum). The motivation here is to issue unused warnings with similar reasoning for any unused lint, and to error for cases where there are conflicts. This also adds a check for empty attribute lists in a few attributes where this causes the attribute to be ignored. Closes #55112.
2021-11-21Auto merge of #90352 - camsteffen:for-loop-desugar, r=oli-obkbors-416/+202
Simplify `for` loop desugar Basically two intermediate bindings are inlined. I could have left one intermediate binding in place as this would simplify some diagnostic logic, but I think the difference in that regard would be negligible, so it is better to have a minimal HIR. For checking that the pattern is irrefutable, I added a special case when the `match` is found to be non-exhaustive. The reordering of the arms is purely stylistic. I don't *think* there are any perf implications. ```diff match IntoIterator::into_iter($head) { mut iter => { $label: loop { - let mut __next; match Iterator::next(&mut iter) { - Some(val) => __next = val, None => break, + Some($pat) => $block, } - let $pat = __next; - $block } } } ```
2021-11-21Bless coverage testsCameron Steffen-11/+9
2021-11-21Update link_ordinal duplicate attribute handling.Eric Huss-3/+8
This removes the duplicate check, as this is now handled in a centralized location.
2021-11-21clippy: Fix pattern_type_mismatch for loopCameron Steffen-164/+43
2021-11-21Fix Clippy with changed for loop desugarCameron Steffen-140/+90
2021-11-21Simplify for loop desugarCameron Steffen-101/+60
2021-11-21Auto merge of #90844 - camelid:cleanup-vis, r=jyn514bors-74/+41
rustdoc: Finish transition to computed visibility This finishes the transition to using computed visibility in rustdoc.
2021-11-21Auto merge of #91104 - matthiaskrgr:rollup-duk33o1, r=matthiaskrgrbors-17/+101
Rollup of 4 pull requests Successful merges: - #91008 (Adds IEEE 754-2019 minimun and maximum functions for f32/f64) - #91070 (Make `LLVMRustGetOrInsertGlobal` always return a `GlobalVariable`) - #91097 (Add spaces in opaque `impl Trait` with more than one trait) - #91098 (Don't suggest certain fixups (`.field`, `.await`, etc) when reporting errors while matching on arrays ) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2021-11-21Rollup merge of #91098 - compiler-errors:issue-91058, r=estebankMatthias Krüger-0/+26
Don't suggest certain fixups (`.field`, `.await`, etc) when reporting errors while matching on arrays When we have a type mismatch with a `cause.code` that is an `ObligationCauseCode::Pattern`, skip suggesting fixes like adding `.await` or accessing a struct's `.field` if the pattern's `root_ty` differs from the `expected` ty. This occurs in situations like this: ```rust struct S(()); fn main() { let array = [S(())]; match array { [()] => {} _ => {} } } ``` I think what's happening here is a layer of `[_; N]` is peeled off of both types and we end up seeing the mismatch between just `S` and `()`, but when we suggest a fixup, that applies to the expression with type `root_ty`. --- Questions: 1. Should this check live here, above all of the suggestions, or should I push this down into every suggestion when we match `ObligationCauseCode`? 2. Any other `ObligationCauseCode`s to check here? 3. Am I overlooking an easier way to get to this same conclusion without pattern matching on `ObligationCauseCode` and comparing `root_ty`? Fixes #91058
2021-11-21Rollup merge of #91097 - compiler-errors:spaces_in_impl_trait, r=estebankMatthias Krüger-17/+17
Add spaces in opaque `impl Trait` with more than one trait `impl A+B` becomes `impl A + B` r? `@estebank`
2021-11-21Rollup merge of #91070 - cuviper:insert-global, r=nagisaMatthias Krüger-0/+58
Make `LLVMRustGetOrInsertGlobal` always return a `GlobalVariable` `Module::getOrInsertGlobal` returns a `Constant*`, which is a super class of `GlobalVariable`, but if the given type doesn't match an existing declaration, it returns a bitcast of that global instead. This causes UB when we pass that to `LLVMGetVisibility` which unconditionally casts the opaque argument to a `GlobalValue*`. Instead, we can do our own get-or-insert without worrying whether existing types match exactly. It's not relevant when we're just trying to get/set the linkage and visibility, and if types are needed we can bitcast or error nicely from `rustc_codegen_llvm` instead. Fixes #91050, fixes #87933, fixes #87813.
2021-11-20Remove styles for details.undocumentedJacob Hoffman-Andrews-33/+4
The Rust code that generated tags with that class was deleted in 10bafe1975e53769180701508e2b8cd3a3b34a0e.
2021-11-21Auto merge of #89580 - estebank:trait-bounds-are-tricky, r=nagisabors-2593/+1783
Point at source of trait bound obligations in more places Be more thorough in using `ItemObligation` and `BindingObligation` when evaluating obligations so that we can point at trait bounds that introduced unfulfilled obligations. We no longer incorrectly point at unrelated trait bounds (`substs-ppaux.verbose.stderr`). In particular, we now point at trait bounds on method calls. We no longer point at "obvious" obligation sources (we no longer have a note pointing at `Trait` saying "required by a bound in `Trait`", like in `associated-types-no-suitable-supertrait*`). We no longer point at associated items (`ImplObligation`), as they didn't add any user actionable information, they just added noise. Address part of #89418.
2021-11-20Fix for issue 91058Michael Goulet-20/+22
2021-11-21Auto merge of #91073 - camelid:small-cleanups, r=jyn514bors-6/+10
rustdoc: Make two small cleanups
2021-11-20Use same_type_modulo_infer in more placesMichael Goulet-0/+24
2021-11-20Fixup test outputsMichael Goulet-17/+17
2021-11-20Move the issue-91050 tests to appease tidyJosh Stone-0/+0
2021-11-20Add another test variant of issue-91050Josh Stone-1/+25
Co-authored-by: Simonas Kazlauskas <git@kazlauskas.me>
2021-11-20Rollup merge of #91022 - compiler-errors:modulo_infer, r=estebankMatthias Krüger-1/+54
Suggest `await` in more situations where infer types are involved Currently we use `TyS::same_type` in diagnostics that suggest adding `.await` to opaque future types. This change makes the suggestion slightly more general, when we're comparing types like `Result<T, E>` and `Result<_, _>` which happens sometimes in places like `match` patterns or `let` statements with partially-elaborated types. ---- Question: 1. Is this change worthwhile? Totally fine if it doesn't make sense adding. 2. Should `same_type_modulo_infer` live in `rustc_infer::infer::error_reporting` or alongside the other method in `rustc_middle::ty::util`? 3. Should we generalize this change? I wanted to change all usages, but I don't want erroneous suggestions when adding `.field_name`...
2021-11-20Rollup merge of #90994 - Badel2:issue-90993, r=estebankMatthias Krüger-0/+37
Fix ICE `#90993`: add missing call to cancel Fix #90993
2021-11-20Rollup merge of #90927 - terrarier2111:fix-float-ice, r=jackh726Matthias Krüger-1/+27
Fix float ICE This fixes https://github.com/rust-lang/rust/issues/90728
2021-11-20bless NLL testEsteban Kuber-0/+18
2021-11-20Move tests from ui directoryEsteban Kuber-0/+0
2021-11-20Move tests for missing trait bounds to their own directoryEsteban Kuber-0/+0
2021-11-20Suggest constraining `fn` type params when appropriateEsteban Kuber-2/+39
2021-11-20Point at `impl` blocks when they introduce unmet obligationsEsteban Kuber-38/+53
Group obligations by `impl` block that introduced them.
2021-11-20Align multiline messages to their label (add left margin)Esteban Kuber-1296/+1294
2021-11-20Do not mention associated items when they introduce an obligationEsteban Kuber-1018/+6
2021-11-20Point at bounds when comparing impl items to traitEsteban Kuber-45/+41
2021-11-20Change `trait_defs.rs` incremental hash testEsteban Kuber-3/+3
`predicates_of` no longer changes when changing a trait's front matter because we no longer include the trait's span in the identity trait obligation.
2021-11-20Point at source of trait bound obligations in more placesEsteban Kuber-341/+479
Be more thorough in using `ItemObligation` and `BindingObligation` when evaluating obligations so that we can point at trait bounds that introduced unfulfilled obligations. We no longer incorrectly point at unrelated trait bounds (`substs-ppaux.verbose.stderr`). In particular, we now point at trait bounds on method calls. We no longer point at "obvious" obligation sources (we no longer have a note pointing at `Trait` saying "required by a bound in `Trait`", like in `associated-types-no-suitable-supertrait*`). Address part of #89418.
2021-11-20Re-bless test outputsMichael Goulet-2/+2
2021-11-20Suggest await on cases involving inferMichael Goulet-1/+54
2021-11-20Fix float ICEthreadexception-1/+27
Co-authored-by: Esteban Kuber <estebank@users.noreply.github.com>
2021-11-20Auto merge of #91066 - camelid:externs, r=jyn514,GuillaumeGomezbors-39/+28
rustdoc: Remove `Crate.externs` and compute on-demand instead r? `@GuillaumeGomez` cc `@jyn514`
2021-11-20Move parser tests to parser/issues subdirectoryBadel2-0/+0
Because the parser directory has already reached the 1000 file limit.
2021-11-20Fix ICE `#90993`: add missing call to cancelBadel2-0/+37
2021-11-20Move `scripts` on the rustdoc template into `head` and apply the `defer` ↵Ken Matsui-10/+10
attribute
2021-11-20Rollup merge of #91021 - compiler-errors:print_future_output, r=estebankMatthias Krüger-64/+64
Elaborate `Future::Output` when printing opaque `impl Future` type I would love to see the `Output =` type when printing type errors involving opaque `impl Future`. [Test code](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=a800b481edd31575fbcaf5771a9c3678) Before (cut relevant part of output): ``` note: while checking the return type of the `async fn` --> /home/michael/test.rs:5:19 | 5 | async fn bar() -> usize { | ^^^^^ checked the `Output` of this `async fn`, found opaque type = note: expected type `usize` found opaque type `impl Future` ``` After: ``` note: while checking the return type of the `async fn` --> /home/michael/test.rs:5:19 | 5 | async fn bar() -> usize { | ^^^^^ checked the `Output` of this `async fn`, found opaque type = note: expected type `usize` found opaque type `impl Future<Output = usize>` ``` Note the "found opaque type `impl Future<Output = usize>`" in the new output. ---- Questions: 1. We skip printing the output type when it's a projection, since I have been seeing some types like `impl Future<Output = <[static generator@/home/michael/test.rs:2:11: 2:21] as Generator<ResumeTy>>::Return>` which are not particularly helpful and leak implementation detail. * Am I able to normalize this type within `rustc_middle::ty::print::pretty`? Alternatively, can we normalize it when creating the diagnostic? Otherwise, I'm fine with skipping it and falling back to the old output. * Should I suppress any other types? I didn't encounter anything other than this generator projection type. 2. Not sure what the formatting of this should be. Do I include spaces in `Output = `?
2021-11-20Rollup merge of #90983 - GuillaumeGomez:sidebar-scrollbar, r=jshaMatthias Krüger-4/+4
Make scrollbar in the sidebar always visible for visual consistency Fixes #90943. I had to add a background in `dark` and `ayu` themes, otherwise it was looking strange (like an invisible margin). So it looks like this: ![Screenshot from 2021-11-17 14-45-49](https://user-images.githubusercontent.com/3050060/142212476-18892ae0-ba4b-48e3-8c0f-4ca1dd2f851d.png) ![Screenshot from 2021-11-17 14-45-53](https://user-images.githubusercontent.com/3050060/142212482-e97b2fad-68d2-439a-b62e-b56e6ded5345.png) Sadly, I wasn't able to add a GUI test to ensure that the scrollbar was always displayed because it seems not possible in puppeteer for whatever reason... I used this method: on small pages (like `lib2/sub_mod/index.html`), comparing `.navbar`'s `clientWidth` with `offsetWidth` (the first doesn't include the sidebar in the computed amount). When checking in the browser, it works fine but in puppeteer it almost never works... In case anyone want to try to solve the bug, here is the puppeteer code: <details> More information about this: I tried another approach which was to get the element in `evaluate` directly (by calling it from `page.evaluate(() => { .. });` directly instead of `parseAssertElemProp.evaluate(e => {...});`. ```js const puppeteer = require('puppeteer'); (async () => { const browser = await puppeteer.launch(); const page = await browser.newPage(); await page.goto("file:///path/rust/build/x86_64-unknown-linux-gnu/test/rustdoc-gui/doc/lib2/sub_mod/index.html"); await page.waitFor(".sidebar"); let parseAssertElemProp = await page.$(".sidebar"); if (parseAssertElemProp === null) { throw '".sidebar" not found'; } await parseAssertElemProp.evaluate(e => { const parseAssertElemPropDict = {"clientWidth": "192", "offsetWidth":"200"}; for (const [parseAssertElemPropKey, parseAssertElemPropValue] of Object.entries(parseAssertElemPropDict)) { if (e[parseAssertElemPropKey] === undefined || String(e[parseAssertElemPropKey]) != parseAssertElemPropValue) { throw 'expected `' + parseAssertElemPropValue + '` for property `' + parseAssertElemPropKey + '` for selector `.sidebar`, found `' + e[parseAssertElemPropKey] + '`'; } } }).catch(e => console.error(e)); await browser.close(); })(); ``` </details> r? ``@jsha``
2021-11-20Rollup merge of #90930 - Nilstrieb:fix-non-const-value-ice, r=estebankMatthias Krüger-1/+110
Fix `non-constant value` ICE (#90878) This also fixes the same suggestion, which was kind of broken, because it just searched for the last occurence of `const` to replace with a `let`. This works great in some cases, but when there is no const and a leading space to the file, it doesn't work and panic with overflow because it thought that it had found a const. I also changed the suggestion to only trigger if the `const` and the non-constant value are on the same line, because if they aren't, the suggestion is very likely to be wrong. Also don't trigger the suggestion if the found `const` is on line 0, because that triggers the ICE. Asking Esteban to review since he was the last one to change the relevant code. r? ``@estebank`` Fixes #90878
2021-11-20Rollup merge of #90628 - ↵Matthias Krüger-15/+301
ken-matsui:clarify-error-messages-caused-by-reexporting-pub-crate-visibility-to-outside, r=oli-obk Clarify error messages caused by re-exporting `pub(crate)` visibility to outside This PR clarifies error messages and suggestions caused by re-exporting pub(crate) visibility outside the crate. Here is a small example ([Rust Playground](https://play.rust-lang.org/?version=nightly&mode=debug&edition=2018&gist=e2cd0bd4422d4f20e6522dcbad167d3b)): ```rust mod m { pub(crate) enum E {} } pub use m::E; fn main() {} ``` This code is compiled to: ``` error[E0365]: `E` is private, and cannot be re-exported --> prog.rs:4:9 | 4 | pub use m::E; | ^^^^ re-export of private `E` | = note: consider declaring type or module `E` with `pub` error: aborting due to previous error For more information about this error, try `rustc --explain E0365`. ``` However, enum `E` is actually public to the crate, not private totally—nevertheless, rustc treats `pub(crate)` and private visibility as the same on the error messages. They are not clear and should be segmented distinctly. By applying changes in this PR, the error message below will be the following message that would be clearer: ``` error[E0365]: `E` is only public to inside of the crate, and cannot be re-exported outside --> prog.rs:4:9 | 4 | pub use m::E; | ^^^^ re-export of crate public `E` | = note: consider declaring type or module `E` with `pub` error: aborting due to previous error For more information about this error, try `rustc --explain E0365`. ```
2021-11-20Rollup merge of #90575 - m-ou-se:compatible-variant-improvements, r=estebankMatthias Krüger-38/+227
Improve suggestions for compatible variants on type mismatch. Fixes #90553. Before: ![image](https://user-images.githubusercontent.com/783247/140385675-6ff41090-eca2-41bc-b161-99c5dabfec61.png) After: ![image](https://user-images.githubusercontent.com/783247/140385748-20cf26b5-ea96-4e56-8af2-5fe1ab16fd3b.png) r? `````@estebank`````
2021-11-19Make `LLVMRustGetOrInsertGlobal` always return a `GlobalVariable`Josh Stone-0/+34
`Module::getOrInsertGlobal` returns a `Constant*`, which is a super class of `GlobalVariable`, but if the given type doesn't match an existing declaration, it returns a bitcast of that global instead. This causes UB when we pass that to `LLVMGetVisibility` which unconditionally casts the opaque argument to a `GlobalValue*`. Instead, we can do our own get-or-insert without worrying whether existing types match exactly. It's not relevant when we're just trying to get/set the linkage and visibility, and if types are needed we can bitcast or error nicely from `rustc_codegen_llvm` instead.
2021-11-19rustdoc: Move doc-reachability visiting back to cleaningNoah Lev-3/+6
It populates `cx.cache.access_levels`, which seems to be needed during cleaning since a bunch of tests are failing.