From 2b86ffc57e09b74e522c9fcd32f39ae9b0c0a05c Mon Sep 17 00:00:00 2001 From: y21 <30553356+y21@users.noreply.github.com> Date: Thu, 10 Oct 2024 18:05:29 +0200 Subject: only emit `manual_c_str_literals` in >= edition2021 --- clippy_lints/src/methods/manual_c_str_literals.rs | 3 + tests/ui/manual_c_str_literals.edition2021.fixed | 63 +++++++++++++++++ tests/ui/manual_c_str_literals.edition2021.stderr | 83 +++++++++++++++++++++++ tests/ui/manual_c_str_literals.fixed | 60 ---------------- tests/ui/manual_c_str_literals.rs | 3 + tests/ui/manual_c_str_literals.stderr | 83 ----------------------- 6 files changed, 152 insertions(+), 143 deletions(-) create mode 100644 tests/ui/manual_c_str_literals.edition2021.fixed create mode 100644 tests/ui/manual_c_str_literals.edition2021.stderr delete mode 100644 tests/ui/manual_c_str_literals.fixed delete mode 100644 tests/ui/manual_c_str_literals.stderr diff --git a/clippy_lints/src/methods/manual_c_str_literals.rs b/clippy_lints/src/methods/manual_c_str_literals.rs index 96af9db1af7..f991e6bc900 100644 --- a/clippy_lints/src/methods/manual_c_str_literals.rs +++ b/clippy_lints/src/methods/manual_c_str_literals.rs @@ -6,6 +6,7 @@ use rustc_ast::{LitKind, StrStyle}; use rustc_errors::Applicability; use rustc_hir::{Expr, ExprKind, Node, QPath, TyKind}; use rustc_lint::LateContext; +use rustc_span::edition::Edition::Edition2021; use rustc_span::{Span, Symbol, sym}; use super::MANUAL_C_STR_LITERALS; @@ -25,6 +26,7 @@ pub(super) fn check_as_ptr<'tcx>( ) { if let ExprKind::Lit(lit) = receiver.kind && let LitKind::ByteStr(_, StrStyle::Cooked) | LitKind::Str(_, StrStyle::Cooked) = lit.node + && cx.tcx.sess.edition() >= Edition2021 && let casts_removed = peel_ptr_cast_ancestors(cx, expr) && !get_parent_expr(cx, casts_removed).is_some_and( |parent| matches!(parent.kind, ExprKind::Call(func, _) if is_c_str_function(cx, func).is_some()), @@ -66,6 +68,7 @@ fn is_c_str_function(cx: &LateContext<'_>, func: &Expr<'_>) -> Option { pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, func: &Expr<'_>, args: &[Expr<'_>], msrv: &Msrv) { if let Some(fn_name) = is_c_str_function(cx, func) && let [arg] = args + && cx.tcx.sess.edition() >= Edition2021 && msrv.meets(msrvs::C_STR_LITERALS) { match fn_name.as_str() { diff --git a/tests/ui/manual_c_str_literals.edition2021.fixed b/tests/ui/manual_c_str_literals.edition2021.fixed new file mode 100644 index 00000000000..391c63bb4b8 --- /dev/null +++ b/tests/ui/manual_c_str_literals.edition2021.fixed @@ -0,0 +1,63 @@ +//@revisions: edition2018 edition2021 +//@[edition2018] edition:2018 +//@[edition2021] edition:2021 +#![warn(clippy::manual_c_str_literals)] +#![allow(clippy::no_effect)] + +use std::ffi::CStr; + +macro_rules! cstr { + ($s:literal) => { + CStr::from_bytes_with_nul(concat!($s, "\0").as_bytes()).unwrap() + }; +} + +macro_rules! macro_returns_c_str { + () => { + CStr::from_bytes_with_nul(b"foo\0").unwrap(); + }; +} + +macro_rules! macro_returns_byte_string { + () => { + b"foo\0" + }; +} + +#[clippy::msrv = "1.76.0"] +fn pre_stabilization() { + CStr::from_bytes_with_nul(b"foo\0"); +} + +#[clippy::msrv = "1.77.0"] +fn post_stabilization() { + c"foo"; +} + +fn main() { + c"foo"; + c"foo"; + c"foo"; + c"foo\\0sdsd"; + CStr::from_bytes_with_nul(br"foo\\0sdsd\0").unwrap(); + CStr::from_bytes_with_nul(br"foo\x00").unwrap(); + CStr::from_bytes_with_nul(br##"foo#a\0"##).unwrap(); + + unsafe { c"foo" }; + unsafe { c"foo" }; + let _: *const _ = c"foo".as_ptr(); + let _: *const _ = c"foo".as_ptr(); + let _: *const _ = "foo".as_ptr(); // not a C-string + let _: *const _ = "".as_ptr(); + let _: *const _ = c"foo".as_ptr().cast::(); + let _ = "电脑".as_ptr(); + let _ = "电脑\\".as_ptr(); + let _ = c"电脑\\".as_ptr(); + let _ = c"电脑".as_ptr(); + let _ = c"电脑".as_ptr(); + + // Macro cases, don't lint: + cstr!("foo"); + macro_returns_c_str!(); + CStr::from_bytes_with_nul(macro_returns_byte_string!()).unwrap(); +} diff --git a/tests/ui/manual_c_str_literals.edition2021.stderr b/tests/ui/manual_c_str_literals.edition2021.stderr new file mode 100644 index 00000000000..beab29ccdda --- /dev/null +++ b/tests/ui/manual_c_str_literals.edition2021.stderr @@ -0,0 +1,83 @@ +error: calling `CStr::new` with a byte string literal + --> tests/ui/manual_c_str_literals.rs:34:5 + | +LL | CStr::from_bytes_with_nul(b"foo\0"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use a `c""` literal: `c"foo"` + | + = note: `-D clippy::manual-c-str-literals` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::manual_c_str_literals)]` + +error: calling `CStr::new` with a byte string literal + --> tests/ui/manual_c_str_literals.rs:38:5 + | +LL | CStr::from_bytes_with_nul(b"foo\0"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use a `c""` literal: `c"foo"` + +error: calling `CStr::new` with a byte string literal + --> tests/ui/manual_c_str_literals.rs:39:5 + | +LL | CStr::from_bytes_with_nul(b"foo\x00"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use a `c""` literal: `c"foo"` + +error: calling `CStr::new` with a byte string literal + --> tests/ui/manual_c_str_literals.rs:40:5 + | +LL | CStr::from_bytes_with_nul(b"foo\0").unwrap(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use a `c""` literal: `c"foo"` + +error: calling `CStr::new` with a byte string literal + --> tests/ui/manual_c_str_literals.rs:41:5 + | +LL | CStr::from_bytes_with_nul(b"foo\\0sdsd\0").unwrap(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use a `c""` literal: `c"foo\\0sdsd"` + +error: calling `CStr::from_ptr` with a byte string literal + --> tests/ui/manual_c_str_literals.rs:46:14 + | +LL | unsafe { CStr::from_ptr(b"foo\0".as_ptr().cast()) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use a `c""` literal: `c"foo"` + +error: calling `CStr::from_ptr` with a byte string literal + --> tests/ui/manual_c_str_literals.rs:47:14 + | +LL | unsafe { CStr::from_ptr(b"foo\0".as_ptr() as *const _) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use a `c""` literal: `c"foo"` + +error: manually constructing a nul-terminated string + --> tests/ui/manual_c_str_literals.rs:48:23 + | +LL | let _: *const _ = b"foo\0".as_ptr(); + | ^^^^^^^^ help: use a `c""` literal: `c"foo"` + +error: manually constructing a nul-terminated string + --> tests/ui/manual_c_str_literals.rs:49:23 + | +LL | let _: *const _ = "foo\0".as_ptr(); + | ^^^^^^^ help: use a `c""` literal: `c"foo"` + +error: manually constructing a nul-terminated string + --> tests/ui/manual_c_str_literals.rs:52:23 + | +LL | let _: *const _ = b"foo\0".as_ptr().cast::(); + | ^^^^^^^^ help: use a `c""` literal: `c"foo"` + +error: manually constructing a nul-terminated string + --> tests/ui/manual_c_str_literals.rs:55:13 + | +LL | let _ = "电脑\\\0".as_ptr(); + | ^^^^^^^^^^ help: use a `c""` literal: `c"电脑\\"` + +error: manually constructing a nul-terminated string + --> tests/ui/manual_c_str_literals.rs:56:13 + | +LL | let _ = "电脑\0".as_ptr(); + | ^^^^^^^^ help: use a `c""` literal: `c"电脑"` + +error: manually constructing a nul-terminated string + --> tests/ui/manual_c_str_literals.rs:57:13 + | +LL | let _ = "电脑\x00".as_ptr(); + | ^^^^^^^^^^ help: use a `c""` literal: `c"电脑"` + +error: aborting due to 13 previous errors + diff --git a/tests/ui/manual_c_str_literals.fixed b/tests/ui/manual_c_str_literals.fixed deleted file mode 100644 index a24d7088c88..00000000000 --- a/tests/ui/manual_c_str_literals.fixed +++ /dev/null @@ -1,60 +0,0 @@ -#![warn(clippy::manual_c_str_literals)] -#![allow(clippy::no_effect)] - -use std::ffi::CStr; - -macro_rules! cstr { - ($s:literal) => { - CStr::from_bytes_with_nul(concat!($s, "\0").as_bytes()).unwrap() - }; -} - -macro_rules! macro_returns_c_str { - () => { - CStr::from_bytes_with_nul(b"foo\0").unwrap(); - }; -} - -macro_rules! macro_returns_byte_string { - () => { - b"foo\0" - }; -} - -#[clippy::msrv = "1.76.0"] -fn pre_stabilization() { - CStr::from_bytes_with_nul(b"foo\0"); -} - -#[clippy::msrv = "1.77.0"] -fn post_stabilization() { - c"foo"; -} - -fn main() { - c"foo"; - c"foo"; - c"foo"; - c"foo\\0sdsd"; - CStr::from_bytes_with_nul(br"foo\\0sdsd\0").unwrap(); - CStr::from_bytes_with_nul(br"foo\x00").unwrap(); - CStr::from_bytes_with_nul(br##"foo#a\0"##).unwrap(); - - unsafe { c"foo" }; - unsafe { c"foo" }; - let _: *const _ = c"foo".as_ptr(); - let _: *const _ = c"foo".as_ptr(); - let _: *const _ = "foo".as_ptr(); // not a C-string - let _: *const _ = "".as_ptr(); - let _: *const _ = c"foo".as_ptr().cast::(); - let _ = "电脑".as_ptr(); - let _ = "电脑\\".as_ptr(); - let _ = c"电脑\\".as_ptr(); - let _ = c"电脑".as_ptr(); - let _ = c"电脑".as_ptr(); - - // Macro cases, don't lint: - cstr!("foo"); - macro_returns_c_str!(); - CStr::from_bytes_with_nul(macro_returns_byte_string!()).unwrap(); -} diff --git a/tests/ui/manual_c_str_literals.rs b/tests/ui/manual_c_str_literals.rs index 0a007786720..39b62258077 100644 --- a/tests/ui/manual_c_str_literals.rs +++ b/tests/ui/manual_c_str_literals.rs @@ -1,3 +1,6 @@ +//@revisions: edition2018 edition2021 +//@[edition2018] edition:2018 +//@[edition2021] edition:2021 #![warn(clippy::manual_c_str_literals)] #![allow(clippy::no_effect)] diff --git a/tests/ui/manual_c_str_literals.stderr b/tests/ui/manual_c_str_literals.stderr deleted file mode 100644 index 9c70bddb81c..00000000000 --- a/tests/ui/manual_c_str_literals.stderr +++ /dev/null @@ -1,83 +0,0 @@ -error: calling `CStr::new` with a byte string literal - --> tests/ui/manual_c_str_literals.rs:31:5 - | -LL | CStr::from_bytes_with_nul(b"foo\0"); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use a `c""` literal: `c"foo"` - | - = note: `-D clippy::manual-c-str-literals` implied by `-D warnings` - = help: to override `-D warnings` add `#[allow(clippy::manual_c_str_literals)]` - -error: calling `CStr::new` with a byte string literal - --> tests/ui/manual_c_str_literals.rs:35:5 - | -LL | CStr::from_bytes_with_nul(b"foo\0"); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use a `c""` literal: `c"foo"` - -error: calling `CStr::new` with a byte string literal - --> tests/ui/manual_c_str_literals.rs:36:5 - | -LL | CStr::from_bytes_with_nul(b"foo\x00"); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use a `c""` literal: `c"foo"` - -error: calling `CStr::new` with a byte string literal - --> tests/ui/manual_c_str_literals.rs:37:5 - | -LL | CStr::from_bytes_with_nul(b"foo\0").unwrap(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use a `c""` literal: `c"foo"` - -error: calling `CStr::new` with a byte string literal - --> tests/ui/manual_c_str_literals.rs:38:5 - | -LL | CStr::from_bytes_with_nul(b"foo\\0sdsd\0").unwrap(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use a `c""` literal: `c"foo\\0sdsd"` - -error: calling `CStr::from_ptr` with a byte string literal - --> tests/ui/manual_c_str_literals.rs:43:14 - | -LL | unsafe { CStr::from_ptr(b"foo\0".as_ptr().cast()) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use a `c""` literal: `c"foo"` - -error: calling `CStr::from_ptr` with a byte string literal - --> tests/ui/manual_c_str_literals.rs:44:14 - | -LL | unsafe { CStr::from_ptr(b"foo\0".as_ptr() as *const _) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use a `c""` literal: `c"foo"` - -error: manually constructing a nul-terminated string - --> tests/ui/manual_c_str_literals.rs:45:23 - | -LL | let _: *const _ = b"foo\0".as_ptr(); - | ^^^^^^^^ help: use a `c""` literal: `c"foo"` - -error: manually constructing a nul-terminated string - --> tests/ui/manual_c_str_literals.rs:46:23 - | -LL | let _: *const _ = "foo\0".as_ptr(); - | ^^^^^^^ help: use a `c""` literal: `c"foo"` - -error: manually constructing a nul-terminated string - --> tests/ui/manual_c_str_literals.rs:49:23 - | -LL | let _: *const _ = b"foo\0".as_ptr().cast::(); - | ^^^^^^^^ help: use a `c""` literal: `c"foo"` - -error: manually constructing a nul-terminated string - --> tests/ui/manual_c_str_literals.rs:52:13 - | -LL | let _ = "电脑\\\0".as_ptr(); - | ^^^^^^^^^^ help: use a `c""` literal: `c"电脑\\"` - -error: manually constructing a nul-terminated string - --> tests/ui/manual_c_str_literals.rs:53:13 - | -LL | let _ = "电脑\0".as_ptr(); - | ^^^^^^^^ help: use a `c""` literal: `c"电脑"` - -error: manually constructing a nul-terminated string - --> tests/ui/manual_c_str_literals.rs:54:13 - | -LL | let _ = "电脑\x00".as_ptr(); - | ^^^^^^^^^^ help: use a `c""` literal: `c"电脑"` - -error: aborting due to 13 previous errors - -- cgit 1.4.1-3-g733a5