rust-lang / rust-lang/rust-clippy

New lint: Performing arithmetic on numeric value of function pointer

Open
#9,517 10 comments 2 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

A-lint
Dominant language
Rust
Stars
13.5k
Forks
2.2k
Avg merge
2d 10h
Merged PRs (30d)
32

Description

What it does

This lints on any expression of the form some_arithmetic_expr(function_pointer as NumericType, other_type).

For example (note the lack of parenthesis - all of the function used here are function pointers)

let alloc_size: u64 = std::mem::size_of::<f32> as u64 * 5u64;
let extra_space: u32 = 1 + std::mem::size_of::<char> as u32;
Lint Name

function_pointer_arithmetic

Category

correctness

Advantage

Performing arithmetic on a function pointer value (cast as a numeric type) is virtually never correct. Rust provides no guarantees about the relative location of functions in memory, or the actual in-memory assembly code at a function's address. In particular, multiplying or dividing by a pointer value is completely meaningless.

Drawbacks

None

Example

When writing low-level code, it's often useful to calculate sizes by multiplying by std::mem::size_of::<SomeType>. For example:

let alloc_size: u64 = num_elements * std::mem::size_of::<MyType>() as u64

However, Rust allows casting a function pointer to any numeric type. If you accidentally commit the parenthesis in the function call, you'll obtain the following valid code:

let alloc_size: u64 = num_elements * std::mem::size_of::<MyType> as u64

This multiplies a function address by num_elements, which is completely useless. The overall result will be completely unrelated to the size of MyType (and depending on the address of std::mem::size_of::<MyType>, it may also be very large). The code looks almost identical to the correct version, which could make it very difficult to notice the cause of the incorrect value.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start from the proposed function_pointer_arithmetic lint name and the expression examples in the issue, comparing the incorrect function-pointer casts with the intended size_of::<T>() calls. Done means the lint detects arithmetic on function pointers cast to numeric types while avoiding the valid parenthesized function calls described in the examples.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
devtools
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.