Skip to content
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

Rollup of 9 pull requests #78451

Closed
wants to merge 37 commits into from
Closed
Changes from 14 commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
9dadcf8
`warn` -> `debug` in collect
lcnr Oct 25, 2020
0e419ef
check for object safety violations in constants
lcnr Oct 25, 2020
00abef1
libc: 0.2.79 -> 0.2.80
nagisa Oct 25, 2020
8546a80
add fixme
lcnr Oct 26, 2020
60bcc58
debug log `AbstractConst::new`
lcnr Oct 26, 2020
0cf3ce4
build-manifest: refactor checksum generation into a struct
pietroalbini Oct 26, 2020
174ed0c
Remove tokens from foreign items in `TokenStripper`
Aaron1011 Oct 26, 2020
c2f4bbd
build-manifest: add BUILD_MANIFEST_CHECKSUM_CACHE
pietroalbini Oct 26, 2020
53fa22a
Fix some outdated comments
nox Oct 26, 2020
a3623e0
rustc_span: avoid hashing ExpnId tag when using cached hash
tgnottingham Sep 21, 2020
8cf1b0e
Uplift temporary-cstring-as-ptr into rustc
nathanwhit Aug 18, 2020
a2f4afe
Add basic test
nathanwhit Aug 18, 2020
8b65df0
Address review comments
nathanwhit Aug 18, 2020
ce95122
Update doctest
nathanwhit Aug 18, 2020
5643a06
Tweak diagnostic
nathanwhit Aug 18, 2020
737bfef
Change to warn by default / fix typo
nathanwhit Aug 23, 2020
1bcd245
Address review comments
nathanwhit Sep 21, 2020
576eb2a
Write docs for lint / fix review nit
nathanwhit Sep 22, 2020
5ac1688
Remove lint from clippy
nathanwhit Sep 22, 2020
6ba127d
Fix doctest
nathanwhit Sep 22, 2020
0569422
Implement -Z function-sections=yes|no
nox Oct 26, 2020
cb8b901
Address review comments
nathanwhit Oct 26, 2020
39941e6
Fix bootstrap doctest failure
nathanwhit Oct 27, 2020
650e3cb
Prefer new associated numeric consts in float error messages
Rustin170506 Oct 27, 2020
572cd35
Fix test
nathanwhit Oct 27, 2020
da64d07
Fix typo in comment
bugadani Oct 27, 2020
99320b9
Fix typos in arena comments
bugadani Oct 27, 2020
b01c74b
Fix typo in vec_graph
bugadani Oct 27, 2020
b2e935d
Rollup merge of #75671 - nathanwhit:cstring-temp-lint, r=oli-obk
jonas-schievink Oct 27, 2020
3861024
Rollup merge of #78365 - lcnr:const-eval-obj-safety, r=oli-obk
jonas-schievink Oct 27, 2020
3e49068
Rollup merge of #78378 - nagisa:nagisa/libc-up, r=Mark-Simulacrum
jonas-schievink Oct 27, 2020
944a4b0
Rollup merge of #78408 - Aaron1011:fix/remove-foreign-tokens, r=oli-obk
jonas-schievink Oct 27, 2020
163b322
Rollup merge of #78409 - pietroalbini:build-manifest-checksum-cache, …
jonas-schievink Oct 27, 2020
f29e191
Rollup merge of #78414 - nox:function-sections, r=nagisa,bjorn3
jonas-schievink Oct 27, 2020
afbc67b
Rollup merge of #78415 - tgnottingham:expn_id_tag_hash, r=Aaron1011
jonas-schievink Oct 27, 2020
2ddaa60
Rollup merge of #78431 - Rustin-Liu:rustin-patch-lint, r=estebank
jonas-schievink Oct 27, 2020
733e3c5
Rollup merge of #78447 - bugadani:typo, r=matthewjasper
jonas-schievink Oct 27, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions compiler/rustc_lint/src/lib.rs
Original file line number Diff line number Diff line change
@@ -49,6 +49,7 @@ mod early;
mod internal;
mod late;
mod levels;
mod methods;
mod non_ascii_idents;
mod nonstandard_style;
mod passes;
@@ -73,6 +74,7 @@ use rustc_span::Span;
use array_into_iter::ArrayIntoIter;
use builtin::*;
use internal::*;
use methods::*;
use non_ascii_idents::*;
use nonstandard_style::*;
use redundant_semicolon::*;
@@ -160,6 +162,7 @@ macro_rules! late_lint_passes {
ArrayIntoIter: ArrayIntoIter,
ClashingExternDeclarations: ClashingExternDeclarations::new(),
DropTraitConstraints: DropTraitConstraints,
TemporaryCStringAsPtr: TemporaryCStringAsPtr,
]
);
};
106 changes: 106 additions & 0 deletions compiler/rustc_lint/src/methods.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
use crate::LateContext;
use crate::LateLintPass;
use crate::LintContext;
use rustc_hir::{Expr, ExprKind, PathSegment};
use rustc_middle::ty;
use rustc_span::{symbol::sym, ExpnKind, Span};

declare_lint! {
/// The `temporary_cstring_as_ptr` lint detects getting the inner pointer of
/// a temporary `CString`.
///
/// ### Example
///
/// ```rust
/// # #![allow(unused)]
/// # use std::ffi::CString;
/// let c_str = CString::new("foo").unwrap().as_ptr();
/// ```
///
/// {{produces}}
///
/// ### Explanation
///
/// The inner pointer of a `CString` lives only as long as the `CString` it
/// points to. Getting the inner pointer of a *temporary* `CString` allows the `CString`
/// to be dropped at the end of the statement, as it is not being referenced as far as the typesystem
/// is concerned. This means outside of the statement the pointer will point to freed memory, which
/// causes undefined behavior if the pointer is later dereferenced.
pub TEMPORARY_CSTRING_AS_PTR,
Warn,
"detects getting the inner pointer of a temporary `CString`"
}

declare_lint_pass!(TemporaryCStringAsPtr => [TEMPORARY_CSTRING_AS_PTR]);

fn in_macro(span: Span) -> bool {
if span.from_expansion() {
!matches!(span.ctxt().outer_expn_data().kind, ExpnKind::Desugaring(..))
} else {
false
}
}

fn first_method_call<'tcx>(
expr: &'tcx Expr<'tcx>,
) -> Option<(&'tcx PathSegment<'tcx>, &'tcx [Expr<'tcx>])> {
if let ExprKind::MethodCall(path, _, args, _) = &expr.kind {
if args.iter().any(|e| e.span.from_expansion()) { None } else { Some((path, *args)) }
} else {
None
}
}

impl<'tcx> LateLintPass<'tcx> for TemporaryCStringAsPtr {
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
if in_macro(expr.span) {
return;
}

match first_method_call(expr) {
Some((path, args)) if path.ident.name == sym::as_ptr => {
let unwrap_arg = &args[0];
let as_ptr_span = path.ident.span;
match first_method_call(unwrap_arg) {
Some((path, args))
if path.ident.name == sym::unwrap || path.ident.name == sym::expect =>
{
let source_arg = &args[0];
lint_cstring_as_ptr(cx, as_ptr_span, source_arg, unwrap_arg);
}
_ => return,
}
}
_ => return,
}
}
}

fn lint_cstring_as_ptr(
cx: &LateContext<'_>,
as_ptr_span: Span,
source: &rustc_hir::Expr<'_>,
unwrap: &rustc_hir::Expr<'_>,
) {
let source_type = cx.typeck_results().expr_ty(source);
if let ty::Adt(def, substs) = source_type.kind() {
if cx.tcx.is_diagnostic_item(sym::result_type, def.did) {
if let ty::Adt(adt, _) = substs.type_at(0).kind() {
if cx.tcx.is_diagnostic_item(sym::cstring_type, adt.did) {
cx.struct_span_lint(TEMPORARY_CSTRING_AS_PTR, as_ptr_span, |diag| {
let mut diag = diag
.build("getting the inner pointer of a temporary `CString`");
diag.span_label(as_ptr_span, "this pointer will be invalid");
diag.span_label(
unwrap.span,
"this `CString` is deallocated at the end of the statement, bind it to a variable to extend its lifetime",
);
diag.note("pointers do not have a lifetime; when calling `as_ptr` the `CString` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned");
diag.help("for more information, see https://doc.rust-lang.org/reference/destructors.html");
diag.emit();
});
}
}
}
}
}
7 changes: 7 additions & 0 deletions compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
@@ -127,6 +127,7 @@ symbols! {
ArgumentV1,
Arguments,
C,
CString,
Center,
Clone,
Copy,
@@ -261,6 +262,7 @@ symbols! {
arm_target_feature,
array,
arrays,
as_ptr,
as_str,
asm,
assert,
@@ -310,6 +312,7 @@ symbols! {
breakpoint,
bridge,
bswap,
c_str,
c_variadic,
call,
call_mut,
@@ -397,6 +400,7 @@ symbols! {
crate_type,
crate_visibility_modifier,
crt_dash_static: "crt-static",
cstring_type,
ctlz,
ctlz_nonzero,
ctpop,
@@ -478,6 +482,7 @@ symbols! {
existential_type,
exp2f32,
exp2f64,
expect,
expected,
expf32,
expf64,
@@ -501,6 +506,7 @@ symbols! {
fadd_fast,
fdiv_fast,
feature,
ffi,
ffi_const,
ffi_pure,
ffi_returns_twice,
@@ -1170,6 +1176,7 @@ symbols! {
unused_qualifications,
unwind,
unwind_attributes,
unwrap,
unwrap_or,
use_extern_macros,
use_nested_groups,
3 changes: 2 additions & 1 deletion library/std/src/ffi/c_str.rs
Original file line number Diff line number Diff line change
@@ -110,6 +110,7 @@ use crate::sys;
/// of `CString` instances can lead to invalid memory accesses, memory leaks,
/// and other memory errors.
#[derive(PartialEq, PartialOrd, Eq, Ord, Hash, Clone)]
#[cfg_attr(not(test), rustc_diagnostic_item = "cstring_type")]
#[stable(feature = "rust1", since = "1.0.0")]
pub struct CString {
// Invariant 1: the slice ends with a zero byte and has a length of at least one.
@@ -1265,7 +1266,7 @@ impl CStr {
/// behavior when `ptr` is used inside the `unsafe` block:
///
/// ```no_run
/// # #![allow(unused_must_use)]
/// # #![allow(unused_must_use)] #![cfg_attr(not(bootstrap), allow(temporary_cstring_as_ptr))]
/// use std::ffi::CString;
///
/// let ptr = CString::new("Hello").expect("CString::new failed").as_ptr();
11 changes: 11 additions & 0 deletions src/test/ui/lint/lint-temporary-cstring-as-param.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#![deny(temporary_cstring_as_ptr)]

use std::ffi::CString;
use std::os::raw::c_char;

fn some_function(data: *const c_char) {}

fn main() {
some_function(CString::new("").unwrap().as_ptr());
//~^ ERROR getting the inner pointer of a temporary `CString`
}
18 changes: 18 additions & 0 deletions src/test/ui/lint/lint-temporary-cstring-as-param.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
error: getting the inner pointer of a temporary `CString`
--> $DIR/lint-temporary-cstring-as-param.rs:9:45
|
LL | some_function(CString::new("").unwrap().as_ptr());
| ------------------------- ^^^^^^ this pointer will be invalid
| |
| this `CString` is deallocated at the end of the statement, bind it to a variable to extend its lifetime
|
note: the lint level is defined here
--> $DIR/lint-temporary-cstring-as-param.rs:1:9
|
LL | #![deny(temporary_cstring_as_ptr)]
| ^^^^^^^^^^^^^^^^^^^^^^^^
= note: pointers do not have a lifetime; when calling `as_ptr` the `CString` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned
= help: for more information, see https://doc.rust-lang.org/reference/destructors.html

error: aborting due to previous error

9 changes: 9 additions & 0 deletions src/test/ui/lint/lint-temporary-cstring-as-ptr.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// this program is not technically incorrect, but is an obscure enough style to be worth linting
#![deny(temporary_cstring_as_ptr)]

use std::ffi::CString;

fn main() {
let s = CString::new("some text").unwrap().as_ptr();
//~^ ERROR getting the inner pointer of a temporary `CString`
}
18 changes: 18 additions & 0 deletions src/test/ui/lint/lint-temporary-cstring-as-ptr.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
error: getting the inner pointer of a temporary `CString`
--> $DIR/lint-temporary-cstring-as-ptr.rs:7:48
|
LL | let s = CString::new("some text").unwrap().as_ptr();
| ---------------------------------- ^^^^^^ this pointer will be invalid
| |
| this `CString` is deallocated at the end of the statement, bind it to a variable to extend its lifetime
|
note: the lint level is defined here
--> $DIR/lint-temporary-cstring-as-ptr.rs:2:9
|
LL | #![deny(temporary_cstring_as_ptr)]
| ^^^^^^^^^^^^^^^^^^^^^^^^
= note: pointers do not have a lifetime; when calling `as_ptr` the `CString` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned
= help: for more information, see https://doc.rust-lang.org/reference/destructors.html

error: aborting due to previous error

6 changes: 3 additions & 3 deletions src/tools/clippy/.github/driver.sh
Original file line number Diff line number Diff line change
@@ -22,9 +22,9 @@ unset CARGO_MANIFEST_DIR

# Run a lint and make sure it produces the expected output. It's also expected to exit with code 1
# FIXME: How to match the clippy invocation in compile-test.rs?
./target/debug/clippy-driver -Dwarnings -Aunused -Zui-testing --emit metadata --crate-type bin tests/ui/cstring.rs 2> cstring.stderr && exit 1
sed -e "s,tests/ui,\$DIR," -e "/= help/d" cstring.stderr > normalized.stderr
diff normalized.stderr tests/ui/cstring.stderr
./target/debug/clippy-driver -Dwarnings -Aunused -Zui-testing --emit metadata --crate-type bin tests/ui/cast.rs 2> cast.stderr && exit 1
sed -e "s,tests/ui,\$DIR," -e "/= help/d" cast.stderr > normalized.stderr
diff normalized.stderr tests/ui/cast.stderr


# make sure "clippy-driver --rustc --arg" and "rustc --arg" behave the same
3 changes: 0 additions & 3 deletions src/tools/clippy/clippy_lints/src/lib.rs
Original file line number Diff line number Diff line change
@@ -707,7 +707,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
&methods::SKIP_WHILE_NEXT,
&methods::STRING_EXTEND_CHARS,
&methods::SUSPICIOUS_MAP,
&methods::TEMPORARY_CSTRING_AS_PTR,
&methods::UNINIT_ASSUMED_INIT,
&methods::UNNECESSARY_FILTER_MAP,
&methods::UNNECESSARY_FOLD,
@@ -1417,7 +1416,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
LintId::of(&methods::SKIP_WHILE_NEXT),
LintId::of(&methods::STRING_EXTEND_CHARS),
LintId::of(&methods::SUSPICIOUS_MAP),
LintId::of(&methods::TEMPORARY_CSTRING_AS_PTR),
LintId::of(&methods::UNINIT_ASSUMED_INIT),
LintId::of(&methods::UNNECESSARY_FILTER_MAP),
LintId::of(&methods::UNNECESSARY_FOLD),
@@ -1765,7 +1763,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
LintId::of(&mem_replace::MEM_REPLACE_WITH_UNINIT),
LintId::of(&methods::CLONE_DOUBLE_REF),
LintId::of(&methods::ITERATOR_STEP_BY_ZERO),
LintId::of(&methods::TEMPORARY_CSTRING_AS_PTR),
LintId::of(&methods::UNINIT_ASSUMED_INIT),
LintId::of(&methods::ZST_OFFSET),
LintId::of(&minmax::MIN_MAX),
56 changes: 0 additions & 56 deletions src/tools/clippy/clippy_lints/src/methods/mod.rs
Original file line number Diff line number Diff line change
@@ -798,40 +798,6 @@ declare_clippy_lint! {
"using a single-character str where a char could be used, e.g., `_.split(\"x\")`"
}

declare_clippy_lint! {
/// **What it does:** Checks for getting the inner pointer of a temporary
/// `CString`.
///
/// **Why is this bad?** The inner pointer of a `CString` is only valid as long
/// as the `CString` is alive.
///
/// **Known problems:** None.
///
/// **Example:**
/// ```rust
/// # use std::ffi::CString;
/// # fn call_some_ffi_func(_: *const i8) {}
/// #
/// let c_str = CString::new("foo").unwrap().as_ptr();
/// unsafe {
/// call_some_ffi_func(c_str);
/// }
/// ```
/// Here `c_str` points to a freed address. The correct use would be:
/// ```rust
/// # use std::ffi::CString;
/// # fn call_some_ffi_func(_: *const i8) {}
/// #
/// let c_str = CString::new("foo").unwrap();
/// unsafe {
/// call_some_ffi_func(c_str.as_ptr());
/// }
/// ```
pub TEMPORARY_CSTRING_AS_PTR,
correctness,
"getting the inner pointer of a temporary `CString`"
}

declare_clippy_lint! {
/// **What it does:** Checks for calling `.step_by(0)` on iterators which panics.
///
@@ -1406,7 +1372,6 @@ declare_lint_pass!(Methods => [
SINGLE_CHAR_PATTERN,
SINGLE_CHAR_PUSH_STR,
SEARCH_IS_SOME,
TEMPORARY_CSTRING_AS_PTR,
FILTER_NEXT,
SKIP_WHILE_NEXT,
FILTER_MAP,
@@ -1490,7 +1455,6 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
lint_search_is_some(cx, expr, "rposition", arg_lists[1], arg_lists[0], method_spans[1])
},
["extend", ..] => lint_extend(cx, expr, arg_lists[0]),
["as_ptr", "unwrap" | "expect"] => lint_cstring_as_ptr(cx, expr, &arg_lists[1][0], &arg_lists[0][0]),
["nth", "iter"] => lint_iter_nth(cx, expr, &arg_lists, false),
["nth", "iter_mut"] => lint_iter_nth(cx, expr, &arg_lists, true),
["nth", ..] => lint_iter_nth_zero(cx, expr, arg_lists[0]),
@@ -2207,26 +2171,6 @@ fn lint_extend(cx: &LateContext<'_>, expr: &hir::Expr<'_>, args: &[hir::Expr<'_>
}
}

fn lint_cstring_as_ptr(cx: &LateContext<'_>, expr: &hir::Expr<'_>, source: &hir::Expr<'_>, unwrap: &hir::Expr<'_>) {
if_chain! {
let source_type = cx.typeck_results().expr_ty(source);
if let ty::Adt(def, substs) = source_type.kind();
if cx.tcx.is_diagnostic_item(sym!(result_type), def.did);
if match_type(cx, substs.type_at(0), &paths::CSTRING);
then {
span_lint_and_then(
cx,
TEMPORARY_CSTRING_AS_PTR,
expr.span,
"you are getting the inner pointer of a temporary `CString`",
|diag| {
diag.note("that pointer will be invalid outside this expression");
diag.span_help(unwrap.span, "assign the `CString` to a variable to extend its lifetime");
});
}
}
}

fn lint_iter_cloned_collect<'tcx>(cx: &LateContext<'tcx>, expr: &hir::Expr<'_>, iter_args: &'tcx [hir::Expr<'_>]) {
if_chain! {
if is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(expr), sym!(vec_type));
1 change: 0 additions & 1 deletion src/tools/clippy/clippy_lints/src/utils/paths.rs
Original file line number Diff line number Diff line change
@@ -21,7 +21,6 @@ pub const CLONE_TRAIT_METHOD: [&str; 4] = ["core", "clone", "Clone", "clone"];
pub const CMP_MAX: [&str; 3] = ["core", "cmp", "max"];
pub const CMP_MIN: [&str; 3] = ["core", "cmp", "min"];
pub const COW: [&str; 3] = ["alloc", "borrow", "Cow"];
pub const CSTRING: [&str; 4] = ["std", "ffi", "c_str", "CString"];
pub const CSTRING_AS_C_STR: [&str; 5] = ["std", "ffi", "c_str", "CString", "as_c_str"];
pub const DEFAULT_TRAIT: [&str; 3] = ["core", "default", "Default"];
pub const DEFAULT_TRAIT_METHOD: [&str; 4] = ["core", "default", "Default", "default"];
7 changes: 0 additions & 7 deletions src/tools/clippy/src/lintlist/mod.rs
Original file line number Diff line number Diff line change
@@ -2258,13 +2258,6 @@ vec![
deprecation: None,
module: "temporary_assignment",
},
Lint {
name: "temporary_cstring_as_ptr",
group: "correctness",
desc: "getting the inner pointer of a temporary `CString`",
deprecation: None,
module: "methods",
},
Lint {
name: "to_digit_is_some",
group: "style",
24 changes: 0 additions & 24 deletions src/tools/clippy/tests/ui/cstring.rs

This file was deleted.

46 changes: 0 additions & 46 deletions src/tools/clippy/tests/ui/cstring.stderr

This file was deleted.