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

False positive py/uninitialized-local-variable #18390

Open
woodywuuu opened this issue Jan 3, 2025 · 3 comments
Open

False positive py/uninitialized-local-variable #18390

woodywuuu opened this issue Jan 3, 2025 · 3 comments

Comments

@woodywuuu
Copy link

Description of the false positive

Code samples or links to source code

class Foo:
    def foo(self, a, b, c=0):
        start = 0
        visible = not (a == b and c)
        end = start if visible else None
        return end

CodeQL Version: 2.18.3

Alert : Local variable 'visible' may be used before it is initialized.

I suspect that the issue is caused by EssaVariable being unable to locate the assignment statement for the variable visible, but I'm not sure how to modify the ql statement.

@woodywuuu
Copy link
Author

If you modify it to be written like this, it will not be able to detect any issues.

class Foo:
    def foo(self, a, b, c=0):
        start = 0
        # visible = not (a == b and c)
        end = start if visible else None
        return end

@RasmusWL RasmusWL added the Python label Jan 6, 2025
@RasmusWL
Copy link
Member

RasmusWL commented Jan 6, 2025

Thanks for reporting this, I agree that's a FP. We'll take a closer look, but can't make any promises on when we have a fix.

I think I've seen issues with inline if-then-else before, so we might have some context on this already (found it in #10998)

@woodywuuu
Copy link
Author

We conducted some experiments and found that the issue is likely not with the inline if-then-else statement, but rather with the UnaryExpr. Whenever a local variable assignment statement takes the form of a = not (b == c and d), it results in an FP case. However, a BoolExpr like a == b does not cause this issue.

I plan to use a brute-force approach to filter out such cases.

predicate ignore_UnaryExpr(NameNode u) {
  not exists(AssignStmt ass |
    ass.getScope() = u.getScope() and
    ass.getATarget().toString() = u.getId() and
    ass.getValue().toString() = "UnaryExpr"
  )
}

from NameNode u
where uninitialized_local(u) and not explicitly_guarded(u) and ignore_UnaryExpr(u)
select u.getNode(), u.getId()

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants