Skip to content

Commit 5419e7a

Browse files
steeveianlancetaylor
authored andcommitted
cmd/cgo: update JNI's jobject to uintptr check for newer Android NDKs
In Android's NDK16, jobject is now declared as: #ifdef __cplusplus class _jobject {}; typedef _jobject* jobject; #else /* not __cplusplus */ typedef void* jobject; #endif This makes the jobject to uintptr check fail because it expects the following definition: struct _jobject; typedef struct _jobject *jobject; Update the type check to handle that new type definition in both C and C++ modes. Fixes #26213 Change-Id: Ic36d4a5176526998d2d5e4e404f8943961141f7a GitHub-Last-Rev: 42037c3 GitHub-Pull-Request: #26221 Reviewed-on: https://go-review.googlesource.com/122217 Run-TryBot: Ian Lance Taylor <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Keith Randall <[email protected]>
1 parent bccbf59 commit 5419e7a

File tree

6 files changed

+121
-7
lines changed

6 files changed

+121
-7
lines changed

misc/cgo/test/cgo_test.go

+1
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ func Test24206(t *testing.T) { test24206(t) }
9191
func Test25143(t *testing.T) { test25143(t) }
9292
func Test23356(t *testing.T) { test23356(t) }
9393
func Test26066(t *testing.T) { test26066(t) }
94+
func Test26213(t *testing.T) { test26213(t) }
9495

9596
func BenchmarkCgoCall(b *testing.B) { benchCgoCall(b) }
9697
func BenchmarkGoString(b *testing.B) { benchGoString(b) }

misc/cgo/test/issue26213/jni.h

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// Copyright 2018 The Go Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
// It's going to be hard to include a whole real JVM to test this.
6+
// So we'll simulate a really easy JVM using just the parts we need.
7+
8+
// This is the relevant part of jni.h.
9+
10+
// On Android NDK16, jobject is defined like this in C and C++
11+
typedef void* jobject;
12+
13+
typedef jobject jclass;
14+
typedef jobject jthrowable;
15+
typedef jobject jstring;
16+
typedef jobject jarray;
17+
typedef jarray jbooleanArray;
18+
typedef jarray jbyteArray;
19+
typedef jarray jcharArray;
20+
typedef jarray jshortArray;
21+
typedef jarray jintArray;
22+
typedef jarray jlongArray;
23+
typedef jarray jfloatArray;
24+
typedef jarray jdoubleArray;
25+
typedef jarray jobjectArray;
26+
27+
typedef jobject jweak;
28+
29+
// Note: jvalue is already a non-pointer type due to it being a C union.

misc/cgo/test/issue26213/test26213.go

+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
// Copyright 2018 The Go Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
package issue26213
6+
7+
/*
8+
#include "jni.h"
9+
*/
10+
import "C"
11+
import (
12+
"testing"
13+
)
14+
15+
func Test26213(t *testing.T) {
16+
var x1 C.jobject = 0 // Note: 0, not nil. That makes sure we use uintptr for these types.
17+
_ = x1
18+
var x2 C.jclass = 0
19+
_ = x2
20+
var x3 C.jthrowable = 0
21+
_ = x3
22+
var x4 C.jstring = 0
23+
_ = x4
24+
var x5 C.jarray = 0
25+
_ = x5
26+
var x6 C.jbooleanArray = 0
27+
_ = x6
28+
var x7 C.jbyteArray = 0
29+
_ = x7
30+
var x8 C.jcharArray = 0
31+
_ = x8
32+
var x9 C.jshortArray = 0
33+
_ = x9
34+
var x10 C.jintArray = 0
35+
_ = x10
36+
var x11 C.jlongArray = 0
37+
_ = x11
38+
var x12 C.jfloatArray = 0
39+
_ = x12
40+
var x13 C.jdoubleArray = 0
41+
_ = x13
42+
var x14 C.jobjectArray = 0
43+
_ = x14
44+
var x15 C.jweak = 0
45+
_ = x15
46+
}

misc/cgo/test/test26213.go

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// Copyright 2018 The Go Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
package cgotest
6+
7+
import (
8+
"testing"
9+
10+
"./issue26213"
11+
)
12+
13+
func test26213(t *testing.T) {
14+
issue26213.Test26213(t)
15+
}

src/cmd/cgo/gcc.go

+24-6
Original file line numberDiff line numberDiff line change
@@ -2772,13 +2772,31 @@ func (c *typeConv) badJNI(dt *dwarf.TypedefType) bool {
27722772
}
27732773
}
27742774

2775-
// Check that the typedef is:
2776-
// struct _jobject;
2777-
// typedef struct _jobject *jobject;
2775+
// Check that the typedef is either:
2776+
// 1:
2777+
// struct _jobject;
2778+
// typedef struct _jobject *jobject;
2779+
// 2: (in NDK16 in C++)
2780+
// class _jobject {};
2781+
// typedef _jobject* jobject;
2782+
// 3: (in NDK16 in C)
2783+
// typedef void* jobject;
27782784
if ptr, ok := w.Type.(*dwarf.PtrType); ok {
2779-
if str, ok := ptr.Type.(*dwarf.StructType); ok {
2780-
if str.StructName == "_jobject" && str.Kind == "struct" && len(str.Field) == 0 && str.Incomplete {
2781-
return true
2785+
switch v := ptr.Type.(type) {
2786+
case *dwarf.VoidType:
2787+
return true
2788+
case *dwarf.StructType:
2789+
if v.StructName == "_jobject" && len(v.Field) == 0 {
2790+
switch v.Kind {
2791+
case "struct":
2792+
if v.Incomplete {
2793+
return true
2794+
}
2795+
case "class":
2796+
if !v.Incomplete {
2797+
return true
2798+
}
2799+
}
27822800
}
27832801
}
27842802
}

src/cmd/dist/test.go

+6-1
Original file line numberDiff line numberDiff line change
@@ -645,7 +645,7 @@ func (t *tester) registerTests() {
645645
return nil
646646
},
647647
})
648-
if cxx, _ := exec.LookPath(compilerEnvLookup(defaultcxx, goos, goarch)); cxx != "" {
648+
if t.hasCxx() {
649649
t.tests = append(t.tests, distTest{
650650
name: "swig_callback",
651651
heading: "../misc/swig/callback",
@@ -1249,6 +1249,11 @@ func (t *tester) hasBash() bool {
12491249
return true
12501250
}
12511251

1252+
func (t *tester) hasCxx() bool {
1253+
cxx, _ := exec.LookPath(compilerEnvLookup(defaultcxx, goos, goarch))
1254+
return cxx != ""
1255+
}
1256+
12521257
func (t *tester) hasSwig() bool {
12531258
swig, err := exec.LookPath("swig")
12541259
if err != nil {

0 commit comments

Comments
 (0)