Skip to content

Lint str-ptr-in-c-abi discourage str pointers in C ABI fns#17401

Open
fpdotmonkey wants to merge 1 commit into
rust-lang:masterfrom
fpdotmonkey:lint-str-ptr-in-c-abi
Open

Lint str-ptr-in-c-abi discourage str pointers in C ABI fns#17401
fpdotmonkey wants to merge 1 commit into
rust-lang:masterfrom
fpdotmonkey:lint-str-ptr-in-c-abi

Conversation

@fpdotmonkey

Copy link
Copy Markdown

Please write a short comment explaining your change (or "none" for internal only changes)

changelog: str-ptr-in-c-abi: This discourages using a pointer to a str instead of to a CString for extern "C" functions.

This addresses #1236

@rustbot rustbot added the S-waiting-on-community-reviews Status: This is awaiting for positive reviews from the community before a maintainer is assigned. label Jul 10, 2026
@rustbot

rustbot commented Jul 10, 2026

Copy link
Copy Markdown
Collaborator

Thanks for the pull request, and welcome!You should hear from one of our reviewers after this PR is reviewed by at least 2 reviewers from the community

Please see the contribution instructions for more information. Namely, in order to ensure the minimum review times lag, PR authors and assigned reviewers should ensure that the review label (S-waiting-on-review and S-waiting-on-author) stays updated, invoking these commands when appropriate:

  • @rustbot author: the review is finished, PR author should check the comments and take action accordingly
  • @rustbot review: the author is ready for a review, this PR will be queued again in the reviewer's queue

@rustbot rustbot added needs-fcp PRs that add, remove, or rename lints and need an FCP S-waiting-on-review Status: Awaiting review from the assignee but also interested parties labels Jul 10, 2026
@fpdotmonkey fpdotmonkey force-pushed the lint-str-ptr-in-c-abi branch 3 times, most recently from db505ce to 0d5dddd Compare July 10, 2026 20:06
@fpdotmonkey

Copy link
Copy Markdown
Author

I'm not really sure what the failure on Lintcheck is. The error messages sounds like failures in external crates, but that's almost certainly not the case.

@Gri-ffin

Gri-ffin commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

You are currently using fn_sig unconditionally, you should check if it's an FnDef or FnPtr.
@rustbot author

@rustbot rustbot added S-waiting-on-author Status: This is awaiting some action from the author. (Use `@rustbot ready` to update this status) and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties labels Jul 10, 2026
@rustbot

rustbot commented Jul 10, 2026

Copy link
Copy Markdown
Collaborator

Reminder, once the PR becomes ready for a review, use @rustbot ready.

@fpdotmonkey fpdotmonkey force-pushed the lint-str-ptr-in-c-abi branch from 0d5dddd to 5f74d2d Compare July 10, 2026 21:36
@github-actions

github-actions Bot commented Jul 10, 2026

Copy link
Copy Markdown

Lintcheck changes for 9669223

Lint Added Removed Changed
clippy::str_ptr_in_c_abi 1 0 0

This comment will be updated if you push new changes

@fpdotmonkey

Copy link
Copy Markdown
Author

You are currently using fn_sig unconditionally, you should check if it's an FnDef or FnPtr.

Fixed

@rustbot ready

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties and removed S-waiting-on-author Status: This is awaiting some action from the author. (Use `@rustbot ready` to update this status) labels Jul 10, 2026
@rustbot

This comment has been minimized.

This discourages using a pointer to a `str` instead of to a CString for
`extern "C"` functions.
@fpdotmonkey fpdotmonkey force-pushed the lint-str-ptr-in-c-abi branch from 5f74d2d to 9669223 Compare July 11, 2026 11:21
@rustbot

rustbot commented Jul 11, 2026

Copy link
Copy Markdown
Collaborator

This PR was rebased onto a different master commit. Here's a range-diff highlighting what actually changed.

Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers.

@Gri-ffin Gri-ffin left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment on lines +45 to +69
let ExprKind::Call(callee, args) = expr.kind else {
return;
};
// where the signature of the callee shows it is
// extern "C"
if is_extern_c_fn(cx, callee) {
// and takes a raw pointer as an argument
let arg_idxs = raw_pointer_arg_idxs(cx, callee);
if arg_idxs.is_empty() {
return;
}
let relevant_args = arg_idxs
.into_iter()
.filter_map(|idx| args.get(idx))
.map(Clone::clone)
.collect::<Vec<_>>();
let problem_args = args_str_ptr_cast(cx, &relevant_args);
if problem_args.is_empty() {
return;
}
let span: rustc_errors::MultiSpan = problem_args
.into_iter()
.map(|arg| arg.span)
.collect::<Vec<rustc_span::Span>>()
.into();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can combine these checks into an if let chain and use an iterator that only collect at the end. (See review below). then you can pass the spans directly to span_lint_and_help (if they are not empty).

Comment on lines +110 to +138
/// Returns elements from `args` which have a Rust `str` as a raw pointer cast to a raw pointer.
fn args_str_ptr_cast<'tcx>(cx: &LateContext<'tcx>, args: &[Expr<'tcx>]) -> Vec<Expr<'tcx>> {
args.iter()
.filter(|arg| {
// just a simple check for
// `let s: &str; libc::strlen(s.as_ptr() as *const _);`
// or similarly with `as_mut_ptr`/`*mut`
if let ExprKind::Cast(expr, ty) = arg.kind
&& matches!(ty.kind, TyKind::Ptr(_))
&& let ExprKind::MethodCall(method, this, _args, _span) = expr.kind
&& ["as_ptr", "as_mut_ptr"].contains(&method.ident.name.as_str())
&& is_ref_str(cx.typeck_results().expr_ty(this))
{
true
} else {
false
}
})
.map(Clone::clone)
.collect()
}

/// is `ty` either `&str` or `&mut str`?
fn is_ref_str(ty: Ty<'_>) -> bool {
if let rustc_middle::ty::Ref(_, reffed_ty, _) = ty.kind() {
return reffed_ty.is_str();
}
false
}

@Gri-ffin Gri-ffin Jul 11, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can replace this with a single function that checks one argument and returns a bool if it's cast to a raw pointer (for example a is_str_ptr_cast that you can use in the above filter closure in the iterator), you can use expr_ty_adjusted to catch String, etc... instead of being limited to str.
Also you can use sym from clippy_utils instead of comparing strings directly, like this:

....
matches!(method.ident.name, sym::as_ptr | sym::as_mut_ptr)

@rustbot rustbot added S-waiting-on-author Status: This is awaiting some action from the author. (Use `@rustbot ready` to update this status) and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties labels Jul 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

needs-fcp PRs that add, remove, or rename lints and need an FCP S-waiting-on-author Status: This is awaiting some action from the author. (Use `@rustbot ready` to update this status) S-waiting-on-community-reviews Status: This is awaiting for positive reviews from the community before a maintainer is assigned.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants