]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/fix,cmd/cgo,misc/cgo: map the EGLDisplay C type to uintptr in Go
authorElias Naur <elias.naur@gmail.com>
Sat, 15 Dec 2018 16:03:37 +0000 (17:03 +0100)
committerElias Naur <elias.naur@gmail.com>
Sat, 15 Dec 2018 19:27:41 +0000 (19:27 +0000)
Similar to to macOS' CF* types and JNI's jobject and derived types,
the EGLDisplay type is declared as a pointer but can contain
non-pointers (see #27054).
Fix it the same way: map EGLDisplay to uintptr in Go.

Fixes #27054

RELNOTE=yes

Change-Id: I6136f8f8162687c5493b30ed324e29efe55a8fd7
Reviewed-on: https://go-review.googlesource.com/c/154417
Run-TryBot: Elias Naur <elias.naur@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
misc/cgo/test/issue27054/egl.h [new file with mode: 0644]
misc/cgo/test/issue27054/test27054.go [new file with mode: 0644]
src/cmd/cgo/gcc.go
src/cmd/fix/egltype.go [new file with mode: 0644]
src/cmd/fix/egltype_test.go [new file with mode: 0644]

diff --git a/misc/cgo/test/issue27054/egl.h b/misc/cgo/test/issue27054/egl.h
new file mode 100644 (file)
index 0000000..33a759e
--- /dev/null
@@ -0,0 +1,7 @@
+// 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.
+
+// This is the relevant part of EGL/egl.h.
+
+typedef void *EGLDisplay;
diff --git a/misc/cgo/test/issue27054/test27054.go b/misc/cgo/test/issue27054/test27054.go
new file mode 100644 (file)
index 0000000..186f5bd
--- /dev/null
@@ -0,0 +1,17 @@
+// 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 issue27054
+
+/*
+#include "egl.h"
+*/
+import "C"
+import (
+       "testing"
+)
+
+func Test27054(t *testing.T) {
+       var _ C.EGLDisplay = 0 // Note: 0, not nil. That makes sure we use uintptr for this type.
+}
index 1f257d7958ab7e719aa718439c3ee5b70d51d885..27bd59b54e0cc72d4126feba4c51db52ea5820a5 100644 (file)
@@ -3004,6 +3004,9 @@ func (c *typeConv) badPointerTypedef(dt *dwarf.TypedefType) bool {
        if c.badJNI(dt) {
                return true
        }
+       if c.badEGLDisplay(dt) {
+               return true
+       }
        return false
 }
 
@@ -3140,6 +3143,19 @@ func (c *typeConv) badJNI(dt *dwarf.TypedefType) bool {
        return false
 }
 
+func (c *typeConv) badEGLDisplay(dt *dwarf.TypedefType) bool {
+       if dt.Name != "EGLDisplay" {
+               return false
+       }
+       // Check that the typedef is "typedef void *EGLDisplay".
+       if ptr, ok := dt.Type.(*dwarf.PtrType); ok {
+               if _, ok := ptr.Type.(*dwarf.VoidType); ok {
+                       return true
+               }
+       }
+       return false
+}
+
 // jniTypes maps from JNI types that we want to be uintptrs, to the underlying type to which
 // they are mapped. The base "jobject" maps to the empty string.
 var jniTypes = map[string]string{
diff --git a/src/cmd/fix/egltype.go b/src/cmd/fix/egltype.go
new file mode 100644 (file)
index 0000000..c8c4f03
--- /dev/null
@@ -0,0 +1,32 @@
+// 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
+
+import (
+       "go/ast"
+)
+
+func init() {
+       register(eglFix)
+}
+
+var eglFix = fix{
+       name:     "egl",
+       date:     "2018-12-15",
+       f:        eglfix,
+       desc:     `Fixes initializers of EGLDisplay`,
+       disabled: false,
+}
+
+// Old state:
+//   type EGLDisplay unsafe.Pointer
+// New state:
+//   type EGLDisplay uintptr
+// This fix finds nils initializing these types and replaces the nils with 0s.
+func eglfix(f *ast.File) bool {
+       return typefix(f, func(s string) bool {
+               return s == "C.EGLDisplay"
+       })
+}
diff --git a/src/cmd/fix/egltype_test.go b/src/cmd/fix/egltype_test.go
new file mode 100644 (file)
index 0000000..35ffe92
--- /dev/null
@@ -0,0 +1,185 @@
+// Copyright 2017 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 init() {
+       addTestCases(eglTests, eglfix)
+}
+
+var eglTests = []testCase{
+       {
+               Name: "egl.localVariable",
+               In: `package main
+
+import "C"
+
+func f() {
+       var x C.EGLDisplay = nil
+       x = nil
+       x, x = nil, nil
+}
+`,
+               Out: `package main
+
+import "C"
+
+func f() {
+       var x C.EGLDisplay = 0
+       x = 0
+       x, x = 0, 0
+}
+`,
+       },
+       {
+               Name: "egl.globalVariable",
+               In: `package main
+
+import "C"
+
+var x C.EGLDisplay = nil
+
+func f() {
+       x = nil
+}
+`,
+               Out: `package main
+
+import "C"
+
+var x C.EGLDisplay = 0
+
+func f() {
+       x = 0
+}
+`,
+       },
+       {
+               Name: "egl.EqualArgument",
+               In: `package main
+
+import "C"
+
+var x C.EGLDisplay
+var y = x == nil
+var z = x != nil
+`,
+               Out: `package main
+
+import "C"
+
+var x C.EGLDisplay
+var y = x == 0
+var z = x != 0
+`,
+       },
+       {
+               Name: "egl.StructField",
+               In: `package main
+
+import "C"
+
+type T struct {
+       x C.EGLDisplay
+}
+
+var t = T{x: nil}
+`,
+               Out: `package main
+
+import "C"
+
+type T struct {
+       x C.EGLDisplay
+}
+
+var t = T{x: 0}
+`,
+       },
+       {
+               Name: "egl.FunctionArgument",
+               In: `package main
+
+import "C"
+
+func f(x C.EGLDisplay) {
+}
+
+func g() {
+       f(nil)
+}
+`,
+               Out: `package main
+
+import "C"
+
+func f(x C.EGLDisplay) {
+}
+
+func g() {
+       f(0)
+}
+`,
+       },
+       {
+               Name: "egl.ArrayElement",
+               In: `package main
+
+import "C"
+
+var x = [3]C.EGLDisplay{nil, nil, nil}
+`,
+               Out: `package main
+
+import "C"
+
+var x = [3]C.EGLDisplay{0, 0, 0}
+`,
+       },
+       {
+               Name: "egl.SliceElement",
+               In: `package main
+
+import "C"
+
+var x = []C.EGLDisplay{nil, nil, nil}
+`,
+               Out: `package main
+
+import "C"
+
+var x = []C.EGLDisplay{0, 0, 0}
+`,
+       },
+       {
+               Name: "egl.MapKey",
+               In: `package main
+
+import "C"
+
+var x = map[C.EGLDisplay]int{nil: 0}
+`,
+               Out: `package main
+
+import "C"
+
+var x = map[C.EGLDisplay]int{0: 0}
+`,
+       },
+       {
+               Name: "egl.MapValue",
+               In: `package main
+
+import "C"
+
+var x = map[int]C.EGLDisplay{0: nil}
+`,
+               Out: `package main
+
+import "C"
+
+var x = map[int]C.EGLDisplay{0: 0}
+`,
+       },
+}