mirror of
https://github.com/golang/go
synced 2024-11-23 07:50:05 -07:00
cmd/gc: correct liveness for func ending in panic
The registerization code needs the function to end in a RET, even if that RET is actually unreachable. The liveness code needs to avoid such unreachable RETs. It had a special case for final RET after JMP, but no case for final RET after UNDEF. Instead of expanding the special cases, let fixjmp - which already knows what is and is not reachable definitively - mark the unreachable RET so that the liveness code can identify it. TBR=iant CC=golang-codereviews https://golang.org/cl/63680043
This commit is contained in:
parent
02ae91f342
commit
ab9e8d068a
@ -519,12 +519,10 @@ newcfg(Prog *firstp)
|
||||
break;
|
||||
bb->last = p;
|
||||
|
||||
// Pattern match an unconditional branch followed by a
|
||||
// dead return instruction. This avoids a creating
|
||||
// Stop before an unreachable RET, to avoid creating
|
||||
// unreachable control flow nodes.
|
||||
if(p->link != nil && p->link->link == nil)
|
||||
if (p->as == AJMP && p->link->as == ARET && p->link->opt == nil)
|
||||
break;
|
||||
if(p->link != nil && p->link->as == ARET && p->link->mode == -1)
|
||||
break;
|
||||
|
||||
// Collect basic blocks with selectgo calls.
|
||||
if(isselectgocall(p))
|
||||
|
@ -146,7 +146,13 @@ fixjmp(Prog *firstp)
|
||||
if(p->opt == dead) {
|
||||
if(p->link == P && p->as == ARET && last && last->as != ARET) {
|
||||
// This is the final ARET, and the code so far doesn't have one.
|
||||
// Let it stay.
|
||||
// Let it stay. The register allocator assumes that all live code in
|
||||
// the function can be traversed by starting at all the RET instructions
|
||||
// and following predecessor links. If we remove the final RET,
|
||||
// this assumption will not hold in the case of an infinite loop
|
||||
// at the end of a function.
|
||||
// Keep the RET but mark it dead for the liveness analysis.
|
||||
p->mode = -1;
|
||||
} else {
|
||||
if(debug['R'] && debug['v'])
|
||||
print("del %P\n", p);
|
||||
|
@ -113,3 +113,11 @@ func f9() bool {
|
||||
x := i9
|
||||
return x != 99
|
||||
}
|
||||
|
||||
// liveness formerly confused by UNDEF followed by RET,
|
||||
// leading to "live at entry to f10: ~r1" (unnamed result).
|
||||
|
||||
func f10() string {
|
||||
panic(1)
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user