// 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)) {
+               // 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.
+               // See issue 29215.
+               return 0
+       }
        return lsym.P[off]
 }
 
 // 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 {
+               return 0
+       }
        if bigEndian {
                return binary.BigEndian.Uint16(lsym.P[off:])
        } else {
 // 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 {
+               return 0
+       }
        if bigEndian {
                return binary.BigEndian.Uint32(lsym.P[off:])
        } else {
 // 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 {
+               return 0
+       }
        if bigEndian {
                return binary.BigEndian.Uint64(lsym.P[off:])
        } else {
 
--- /dev/null
+// compile
+
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+func f() {
+        var s string
+        var p, q bool
+        s = "a"
+        for p {
+                p = false == (true != q)
+                s = ""
+        }
+        _ = s == "bbb"
+}