You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
(This is an issue about less than ideal generated code. I don't know if the project accepts such issues?)
In real programs, I've observed some redundant checks for nil pointers that I think the compiler should be able to optimize away. They seem to have to do with inlined methods.
Here is a reduced test case that panics due to a nil pointer dereference:
The segfault looks like this in GDB (with Intel syntax):
Dump of assembler code for function main.main:
0x0000000000400c00 <+0>: xor eax,eax
0x0000000000400c02 <+2>: cmp rax,0x0
0x0000000000400c06 <+6>: je 0x400c16 <main.main+22>
0x0000000000400c08 <+8>: mov rbp,QWORD PTR [rax+0x8]
0x0000000000400c0c <+12>: mov rbx,QWORD PTR [rax+0x18]
0x0000000000400c10 <+16>: sub rbp,rbx
0x0000000000400c13 <+19>: mov ebx,ebp
0x0000000000400c15 <+21>: ret
=> 0x0000000000400c16 <+22>: mov DWORD PTR [rax],eax
0x0000000000400c18 <+24>: jmp 0x400c08 <main.main+8>
The code checks f for being nil, and intentionally segfaults if so. But I believe it doesn't need to: the compiler knows the minimum page size on the architecture, and knows that Foo is less than a page long. Therefore if f is nil, then f+0x8 will be on the same unmapped page as 0x0, and should segfault just the same as the write to 0x0 that the generated code uses. In other words: the branch need not exist, because the instruction at +8 will already segfault if f is nil.
Indeed when a member of Foo is instead read directly, this fact appears to be used:
adg
changed the title
Redundant checks for nil pointers when calling an inlined method
cmd/compile: redundant checks for nil pointers when calling an inlined method
Jun 30, 2015
(This is an issue about less than ideal generated code. I don't know if the project accepts such issues?)
In real programs, I've observed some redundant checks for nil pointers that I think the compiler should be able to optimize away. They seem to have to do with inlined methods.
Here is a reduced test case that panics due to a nil pointer dereference:
The segfault looks like this in GDB (with Intel syntax):
The code checks
f
for being nil, and intentionally segfaults if so. But I believe it doesn't need to: the compiler knows the minimum page size on the architecture, and knows thatFoo
is less than a page long. Therefore iff
is nil, thenf+0x8
will be on the same unmapped page as0x0
, and should segfault just the same as the write to0x0
that the generated code uses. In other words: the branch need not exist, because the instruction at+8
will already segfault iff
is nil.Indeed when a member of
Foo
is instead read directly, this fact appears to be used:Go version:
The text was updated successfully, but these errors were encountered: