diff --git a/src/cmd/compile/internal/ssa/rewrite.go b/src/cmd/compile/internal/ssa/rewrite.go index 6edb593df97ae6..9c9de750b211b1 100644 --- a/src/cmd/compile/internal/ssa/rewrite.go +++ b/src/cmd/compile/internal/ssa/rewrite.go @@ -1142,7 +1142,7 @@ func symIsRO(sym interface{}) bool { // read8 reads one byte from the read-only global sym at offset off. func read8(sym interface{}, off int64) uint8 { lsym := sym.(*obj.LSym) - if off >= int64(len(lsym.P)) { + if off >= int64(len(lsym.P)) || off < 0 { // Invalid index into the global sym. // This can happen in dead code, so we don't want to panic. // Just return any value, it will eventually get ignored. @@ -1155,7 +1155,7 @@ func read8(sym interface{}, off int64) uint8 { // read16 reads two bytes from the read-only global sym at offset off. func read16(sym interface{}, off int64, bigEndian bool) uint16 { lsym := sym.(*obj.LSym) - if off >= int64(len(lsym.P))-1 { + if off >= int64(len(lsym.P))-1 || off < 0 { return 0 } if bigEndian { @@ -1168,7 +1168,7 @@ func read16(sym interface{}, off int64, bigEndian bool) uint16 { // read32 reads four bytes from the read-only global sym at offset off. func read32(sym interface{}, off int64, bigEndian bool) uint32 { lsym := sym.(*obj.LSym) - if off >= int64(len(lsym.P))-3 { + if off >= int64(len(lsym.P))-3 || off < 0 { return 0 } if bigEndian { @@ -1181,7 +1181,7 @@ func read32(sym interface{}, off int64, bigEndian bool) uint32 { // read64 reads eight bytes from the read-only global sym at offset off. func read64(sym interface{}, off int64, bigEndian bool) uint64 { lsym := sym.(*obj.LSym) - if off >= int64(len(lsym.P))-7 { + if off >= int64(len(lsym.P))-7 || off < 0 { return 0 } if bigEndian { diff --git a/test/fixedbugs/issue29215.go b/test/fixedbugs/issue29215.go index df703aa25d7e8e..4e8f107aee585b 100644 --- a/test/fixedbugs/issue29215.go +++ b/test/fixedbugs/issue29215.go @@ -16,3 +16,20 @@ func f() { } _ = s == "bbb" } + +// Another case: load from negative offset of a symbol +// in dead code (issue 30257). +func g() { + var i int + var s string + + if true { + s = "a" + } + + if f := 0.0; -f < 0 { + i = len(s[:4]) + } + + _ = s[i-1:0] != "bb" && true +}