-
Notifications
You must be signed in to change notification settings - Fork 17.9k
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
x/tools/go/analysis/passes/nilness: spurious "impossible/tautological condition" with cond := a != nil; if cond {...}; if cond { ... } #70381
Comments
Hello! I found your issue interesting. I tried to debug the cases you provided and found this. Code assumes that left operand is nil in case of nil right operand. Here is the commit: IlyasYOY/tools@5c4cf21 (you might want to experiment with it)
I'd be glad to dive deeper and find the solution. If there are any hints I'd really appreciate it . |
Thanks for the very thorough bug report! The problem is that the nilness analyzer is not taking care to distinguish whether a condition appears directly within an if condition, or via an intervening variable. In the original test case:
the analyzer detects that the first The analyzer will need to detect whether the condition has multiple referrers; if so, it will need to report that the condition is trivially true/false only for some of them, or, report the error at the |
Unfortunately Some options:
Option 5 is really the only approach that gives us the position of the second If statement, so it's my favorite. But it's a project. |
Long term I think recording the ast.Node unconditionally is likely better for ssa. That extra word per Instruction buys a lot. But I agree option 5 seems like the right short term solution for this. Changing that comment is a waste of the proposal committee's time IMO, but I'll leave that up to you. |
Two words! And it's far from clear what the correct Node is for each Instr once the syntax is all boiled down. |
You get to reclaim the token.Pos so the delta should be +1 word per Instruction (pre-padding/alignment considerations).
Good point. This is much easier if you only need to be consistent within a handful of repos, but ssa does aspire to more consistency than this. |
The Pos is not a field, it's code:
And for the instructions that do have a Pos field, they would still need to keep it because the hypothetical ast.Node field would be potentially nil (or too diverse a range of things to reliably derive pos from it). |
I dont know if my issue matches, but i have the ?same? issue with a nil pointer: type Infos struct {
m map[string]string
}
// ....
var infos *Infos
for k, v := range data {
if v.valid {
if infos == nil { // tautological condition: nil == nil
infos = &Infos{}
}
}
} |
This code isn't valid: Can you provide a working example that reproduces the problem? |
Go version
go version go1.23.0 linux/amd64
Output of
go env
in your module/workspace:What did you do?
I believe there is a bug in the nilness checker that incorrectly reports an impossible "nil != nil" and also omits an error in a different location about a tautological comparison. This code demonstrates it:
I checked here: https://github.com/golang/go/issues?page=1&q=is%3Aissue+is%3Aopen+nilness and I can't find anything that matches.
What did you see happen?
Here is a screenshot for clarity:
What did you expect to see?
The above error implies that
a
is alwaysnil
and thereforea != nil
will never happen. That is not true. However, there still is a problem with the code. Because of thereturn
, then theif !hasA
is tautological -- although, that's a different error, and it's not reported, and the error that is reported is not only erroneous but also in the wrong place.This, for example, correctly reports no errors:
So I would expect to see something like this:
Interestingly, if I just get rid of
hasA
and put the expression directly in theif
statement, I get:That's what I would expect to see whether or not I have the boolean value broken out into a different variable.
The text was updated successfully, but these errors were encountered: