4 ms·
Yeah. The bug is that the compiler propagated not null from main.node to walk.module. But how did the compiler determine main.node is not null?
by tedunangst 7y ago
Yeah. The bug is that the compiler propagated not null from main.node to walk.module.
But how did the compiler determine main.node is not null?
- klodolph 7y ago> But how did the compiler determine main.node is not null? The test case in the bug happens to use UB to generate the constraint, but this is just an example of how to trigger the bug. The bug itself is not related to UB, and there are other ways to generate the same constraint. Here is an example on godbolt showing what I mean: https://godbolt.org/z/pRW97L https://godbolt.org/z/pRW97L You'll notice that I removed the UB, but the bug is still there. You can see that the 'return;' statement is not emitted because it is colored with a white background. So the bug is not related to UB at all.
- tedunangst 7y agoOk, this is the clarification I was seeking.
- saagarjha 7y ago> You can see that the 'return;' statement is not emitted Uh, what? The code looks correct to me: func: test rdi, rdi je .L7 mov esi, 1 jmp walk .L7: ret There's a conditional branch on $rdi that jumps to .L7 (which returns) when node is NULL.
- klodolph 7y agoYou're looking at 'func', the error is in 'walk'. Here is the top of 'walk': walk: push rbx mov rbx, rdi test esi, esi je .L3 mov rdi, QWORD PTR [rdi] call walk Note that esi = cleanup = 1 so the branch to .L3 is not taken, and the recursive call to 'walk' is taken. The crash will occur on the instruction before the call, mov rdi, QWORD PTR [rdi] Because rdi = 0 on the second call to 'walk'.
- saagarjha 7y agoOh, yes, walk is still broken. I was focusing on func because you had added that and it coincidentally also had a white return statement.
- bialpio 7y agoThere's a deref of main.node and dereferencing null pointer is UB so it couldn't have been null?