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 negative with defer #6

Open
maratori opened this issue Jan 2, 2025 · 2 comments
Open

False negative with defer #6

maratori opened this issue Jan 2, 2025 · 2 comments

Comments

@maratori
Copy link

maratori commented Jan 2, 2025

The same issue exists in gostaticanalysis/nilerr#19.

The following test fails:

func TestFails() error {
	defer func() {}() // the test passes if you remove defer
	err := func() error { return nil }()
	if err != nil {
		return err
	}
	err2 := func() error { return nil }()
	if err2 != nil {
		return err // want `return a nil value error after check error`
	}
	return nil
}
@alingse
Copy link
Owner

alingse commented Jan 2, 2025

 🤔 I will check it 🤔

@alingse
Copy link
Owner

alingse commented Jan 2, 2025

I use another function and print the blocks and instrs

func Call18() error {
	defer func() {}() // the test passes if you remove defer

	err := Do()
	if err != nil {
		return err
	}
	err2 := Do2()
	if err2 != nil {
		return err // want `return a nil value error after check error`
	}
	return nil
}
blocks[0].Instrs[0]     *ssa.Alloc      local error ()
blocks[0].Instrs[1]     *ssa.Defer      defer Call18$1()
blocks[0].Instrs[2]     *ssa.Call       Do()
blocks[0].Instrs[3]     *ssa.BinOp      t1 != nil:error
blocks[0].Instrs[4]     *ssa.If if t2 goto 2 else 3

blocks[1].Instrs[0]     *ssa.UnOp       *t0
blocks[1].Instrs[1]     *ssa.Return     return t3

blocks[2].Instrs[0]     *ssa.Store      *t0 = t1
blocks[2].Instrs[1]     *ssa.RunDefers  rundefers
blocks[2].Instrs[2]     *ssa.UnOp       *t0
blocks[2].Instrs[3]     *ssa.Return     return t4

blocks[3].Instrs[0]     *ssa.Call       Do2()
blocks[3].Instrs[1]     *ssa.BinOp      t5 != nil:error
blocks[3].Instrs[2]     *ssa.If if t6 goto 4 else 5

blocks[4].Instrs[0]     *ssa.Store      *t0 = t1
blocks[4].Instrs[1]     *ssa.RunDefers  rundefers
blocks[4].Instrs[2]     *ssa.UnOp       *t0
blocks[4].Instrs[3]     *ssa.Return     return t7

blocks[5].Instrs[0]     *ssa.Store      *t0 = nil:error
blocks[5].Instrs[1]     *ssa.RunDefers  rundefers
blocks[5].Instrs[2]     *ssa.UnOp       *t0
blocks[5].Instrs[3]     *ssa.Return     return t8

the return err was convert to *ssa.Store *t0 = nil:error a store instr, this is not support by nilness, I will try to support it if I can.

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

No branches or pull requests

2 participants