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

rule: intfromptr-compare-with-zero #230

Open
190n opened this issue Feb 12, 2025 · 0 comments
Open

rule: intfromptr-compare-with-zero #230

190n opened this issue Feb 12, 2025 · 0 comments
Labels
A-linter Area - linter and lint rules C-rule Category - Lint rule suggestion

Comments

@190n
Copy link

190n commented Feb 12, 2025

Description

This rule would forbid comparing the result of @intFromPtr(...) with zero, unless the pointer is allowzero (allowzero pointers are rare enough that, if type analysis isn't able to determine pointer annotations, it might be acceptable if you need to manually disable this rule for @intFromPtr calls on allowzero pointers).

For pointers that are neither optional nor allowzero, @intFromPtr will never return zero because such pointers are forbidden from being zero. Optimization knows this and makes a comparison with zero always return false. So this comparison is always a bug.

For optional, non-allowzero pointers, @intFromPtr(p) != 0 does have the intended behavior, but I think it's cleaner to write p != null which is why I'm proposing this rule apply to those pointers too.

Examples

Examples of incorrect code for this rule

pub const Header = struct {
    name: []const u8,
    pub fn isMultiline(self: Header) bool {
        // oops, always false
        return @intFromPtr(self.name.ptr) == 0;
    }
};

pub const Example = struct {
    optional_data: ?*u32,
    pub fn hasData(self: Example) bool {
        // works, but comparison with null is nicer
        return @intFromPtr(self.optional_data) != 0;
    }
};

Examples of correct code for this rule

pub const Header = struct {
    name: []const u8,
    pub fn isMultiline(self: Header) bool {
        return self.name.len == 0;
    }
};

pub const Example = struct {
    optional_data: ?*u32,
    pub fn hasData(self: Example) bool {
        return self.optional_data != null;
    }
};

// for this example suppose you're writing an OS or something
pub const MemoryMapping = struct {
    pages: []allowzero align(4096) const u8,
    pub fn isStartOfAddressSpace(self: MemoryMapping) bool {
        // this code is correct and there's not a better way to express it
        return @intFromPtr(self.pages.ptr) == 0;
    }
};
@190n 190n added A-linter Area - linter and lint rules C-rule Category - Lint rule suggestion labels Feb 12, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-linter Area - linter and lint rules C-rule Category - Lint rule suggestion
Projects
None yet
Development

No branches or pull requests

1 participant