Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion cl/_testdata/varinit/in.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ var a = 100
// CHECK-NEXT: %0 = load i64, ptr @main.a, align 8
// CHECK-NEXT: %1 = add i64 %0, 1
// CHECK-NEXT: store i64 %1, ptr @main.a, align 8
// CHECK-NEXT: %2 = load i64, ptr @main.a, align 8
// CHECK-NEXT: ret void
// CHECK-NEXT: }
func main() {
Expand Down
2 changes: 0 additions & 2 deletions cl/_testrt/cvar/in.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@ var barY struct {

// CHECK-LABEL: define void @main.main(){{.*}} {
// CHECK-NEXT: _llgo_0:
// CHECK-NEXT: %0 = load { [16 x i8], [2 x ptr] }, ptr @_bar_x, align 8
// CHECK-NEXT: %1 = load { [16 x i8] }, ptr @_bar_y, align 1
// CHECK-NEXT: ret void
// CHECK-NEXT: }
func main() {
Expand Down
25 changes: 7 additions & 18 deletions cl/compile.go
Original file line number Diff line number Diff line change
Expand Up @@ -1331,28 +1331,17 @@ func (p *context) compileInstrOrValue(b llssa.Builder, iv instrOrValue, asValue
b.AssertNilDeref(x)
}
if refs, ok := nonDebugReferrers(v); ok && len(refs) == 0 {
if t := p.type_(v.Type(), llssa.InGo); t.RawType() != nil {
if p.isLargeNonPointerValue(t) {
x := p.compileValue(b, v.X)
p.recordPanicLocation(b, v.Pos())
p.assertNilDerefBase(b, v.X)
b.AssertNilDeref(x)
return
}
}
if skipUnusedArrayDeref(v) {
p.compileValue(b, v.X)
return
}
if _, ok := types.Unalias(v.Type()).Underlying().(*types.Slice); ok {
// Zero-length slice-to-array conversions can leave only
// an unused slice deref; preserve its required nil check.
x := p.compileValue(b, v.X)
p.recordPanicLocation(b, v.Pos())
p.assertNilDerefBase(b, v.X)
b.AssertNilDeref(x)
return
}
// LLVM may eliminate an unused load, but evaluating a Go
// dereference must still panic when its pointer is nil.
x := p.compileValue(b, v.X)
Comment thread
cpunion marked this conversation as resolved.
p.recordPanicLocation(b, v.Pos())
p.assertNilDerefBase(b, v.X)
b.AssertNilDeref(x)
return
}
if refs, ok := nonDebugReferrers(v); ok && len(refs) == 1 {
if _, ok := refs[0].(*ssa.MakeInterface); ok {
Expand Down
21 changes: 21 additions & 0 deletions cl/zero_size_deref_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,3 +71,24 @@ func keepPointer(pointer *struct{}) func() bool {
})
}
}

func TestUnusedDerefEmitsNilGuard(t *testing.T) {
const src = `package unusedderef
func LoadArrayElement() {
var values [2]*int
_ = *values[1]
}
func LoadPointer(p *int) {
_ = *p
}
`
ir := compileWithRewrites(t, src, nil)
arrayLoad := llvmFunction(t, ir, "unusedderef.LoadArrayElement")
if !strings.Contains(arrayLoad, "AssertNilDeref") {
t.Fatalf("unused array-element dereference should retain a nil guard:\n%s", arrayLoad)
}
directLoad := llvmFunction(t, ir, "unusedderef.LoadPointer")
if !strings.Contains(directLoad, "AssertNilDeref") {
t.Fatalf("unused direct dereference should retain a nil guard:\n%s", directLoad)
}
}
27 changes: 27 additions & 0 deletions test/go/nil_deref_address_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,33 @@ func TestNilDerefAddressOperationsPanic(t *testing.T) {
}
}

func TestUnusedNilDerefOperationsPanic(t *testing.T) {
tests := []struct {
name string
f func()
}{
{
name: "direct pointer",
f: func() {
var p *int
_ = *p
},
},
{
name: "pointer loaded from array",
f: func() {
var values [2]*int
_ = *values[1]
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
expectNilDerefAddressPanic(t, tt.f)
})
}
}

func TestNilDerefPrintedCompositeLoadsPanic(t *testing.T) {
tests := []struct {
name string
Expand Down
8 changes: 0 additions & 8 deletions test/goroot/xfail.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1559,14 +1559,6 @@ xfails:
directive: run
case: fixedbugs/issue57823.go
reason: go1.26 goroot run failure on linux/amd64
- platform: darwin/arm64
directive: run
case: fixedbugs/issue38496.go
reason: current main goroot run failure on darwin/arm64
- platform: linux/amd64
directive: run
case: fixedbugs/issue38496.go
reason: current main goroot run failure on linux/amd64
- platform: linux/amd64
directive: run
case: nilptr.go
Expand Down
Loading