Skip to content

cmd/cgo: update JNI's jobject to uintptr check for newer Android NDKs #26221

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
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: 1 addition & 0 deletions misc/cgo/test/cgo_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ func Test24206(t *testing.T) { test24206(t) }
func Test25143(t *testing.T) { test25143(t) }
func Test23356(t *testing.T) { test23356(t) }
func Test26066(t *testing.T) { test26066(t) }
func Test26213(t *testing.T) { test26213(t) }

func BenchmarkCgoCall(b *testing.B) { benchCgoCall(b) }
func BenchmarkGoString(b *testing.B) { benchGoString(b) }
29 changes: 29 additions & 0 deletions misc/cgo/test/issue26213/jni.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// 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.

// It's going to be hard to include a whole real JVM to test this.
// So we'll simulate a really easy JVM using just the parts we need.

// This is the relevant part of jni.h.

// On Android NDK16, jobject is defined like this in C and C++
typedef void* jobject;

typedef jobject jclass;
typedef jobject jthrowable;
typedef jobject jstring;
typedef jobject jarray;
typedef jarray jbooleanArray;
typedef jarray jbyteArray;
typedef jarray jcharArray;
typedef jarray jshortArray;
typedef jarray jintArray;
typedef jarray jlongArray;
typedef jarray jfloatArray;
typedef jarray jdoubleArray;
typedef jarray jobjectArray;

typedef jobject jweak;

// Note: jvalue is already a non-pointer type due to it being a C union.
46 changes: 46 additions & 0 deletions misc/cgo/test/issue26213/test26213.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// 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 issue26213

/*
#include "jni.h"
*/
import "C"
import (
"testing"
)

func Test26213(t *testing.T) {
var x1 C.jobject = 0 // Note: 0, not nil. That makes sure we use uintptr for these types.
_ = x1
var x2 C.jclass = 0
_ = x2
var x3 C.jthrowable = 0
_ = x3
var x4 C.jstring = 0
_ = x4
var x5 C.jarray = 0
_ = x5
var x6 C.jbooleanArray = 0
_ = x6
var x7 C.jbyteArray = 0
_ = x7
var x8 C.jcharArray = 0
_ = x8
var x9 C.jshortArray = 0
_ = x9
var x10 C.jintArray = 0
_ = x10
var x11 C.jlongArray = 0
_ = x11
var x12 C.jfloatArray = 0
_ = x12
var x13 C.jdoubleArray = 0
_ = x13
var x14 C.jobjectArray = 0
_ = x14
var x15 C.jweak = 0
_ = x15
}
15 changes: 15 additions & 0 deletions misc/cgo/test/test26213.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// 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 cgotest

import (
"testing"

"./issue26213"
)

func test26213(t *testing.T) {
issue26213.Test26213(t)
}
30 changes: 24 additions & 6 deletions src/cmd/cgo/gcc.go
Original file line number Diff line number Diff line change
Expand Up @@ -2704,13 +2704,31 @@ func (c *typeConv) badJNI(dt *dwarf.TypedefType) bool {
}
}

// Check that the typedef is:
// struct _jobject;
// typedef struct _jobject *jobject;
// Check that the typedef is either:
// 1:
// struct _jobject;
// typedef struct _jobject *jobject;
// 2: (in NDK16 in C++)
// class _jobject {};
// typedef _jobject* jobject;
// 3: (in NDK16 in C)
// typedef void* jobject;
if ptr, ok := w.Type.(*dwarf.PtrType); ok {
if str, ok := ptr.Type.(*dwarf.StructType); ok {
if str.StructName == "_jobject" && str.Kind == "struct" && len(str.Field) == 0 && str.Incomplete {
return true
switch v := ptr.Type.(type) {
case *dwarf.VoidType:
return true
case *dwarf.StructType:
if v.StructName == "_jobject" && len(v.Field) == 0 {
switch v.Kind {
case "struct":
if v.Incomplete {
return true
}
case "class":
if !v.Incomplete {
return true
}
}
}
}
}
Expand Down
7 changes: 6 additions & 1 deletion src/cmd/dist/test.go
Original file line number Diff line number Diff line change
Expand Up @@ -645,7 +645,7 @@ func (t *tester) registerTests() {
return nil
},
})
if cxx, _ := exec.LookPath(compilerEnvLookup(defaultcxx, goos, goarch)); cxx != "" {
if t.hasCxx() {
t.tests = append(t.tests, distTest{
name: "swig_callback",
heading: "../misc/swig/callback",
Expand Down Expand Up @@ -1249,6 +1249,11 @@ func (t *tester) hasBash() bool {
return true
}

func (t *tester) hasCxx() bool {
cxx, _ := exec.LookPath(compilerEnvLookup(defaultcxx, goos, goarch))
return cxx != ""
}

func (t *tester) hasSwig() bool {
swig, err := exec.LookPath("swig")
if err != nil {
Expand Down