]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/cgo: update JNI's jobject to uintptr check for newer Android NDKs
authorSteeve Morin <steeve.morin@gmail.com>
Tue, 17 Jul 2018 15:55:01 +0000 (15:55 +0000)
committerIan Lance Taylor <iant@golang.org>
Tue, 17 Jul 2018 16:51:15 +0000 (16:51 +0000)
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: 42037c3c584579c2b3281c25372b830e864e7aec
GitHub-Pull-Request: golang/go#26221
Reviewed-on: https://go-review.googlesource.com/122217
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
misc/cgo/test/cgo_test.go
misc/cgo/test/issue26213/jni.h [new file with mode: 0644]
misc/cgo/test/issue26213/test26213.go [new file with mode: 0644]
misc/cgo/test/test26213.go [new file with mode: 0644]
src/cmd/cgo/gcc.go
src/cmd/dist/test.go

index ba2a89ef82f5aa804c1ed4a37e0d995c7fceaef0..ccacc50fe1a4f1ee848870e093adcdb2b751f188 100644 (file)
@@ -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) }
diff --git a/misc/cgo/test/issue26213/jni.h b/misc/cgo/test/issue26213/jni.h
new file mode 100644 (file)
index 0000000..0c76979
--- /dev/null
@@ -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.
diff --git a/misc/cgo/test/issue26213/test26213.go b/misc/cgo/test/issue26213/test26213.go
new file mode 100644 (file)
index 0000000..5d1f637
--- /dev/null
@@ -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
+}
diff --git a/misc/cgo/test/test26213.go b/misc/cgo/test/test26213.go
new file mode 100644 (file)
index 0000000..176a7ec
--- /dev/null
@@ -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)
+}
index 251cb18f5ff520f5d2146d87e550e88cb4705cf1..8bd409358778d13d2b704b7d6feb3ebc0b1c119e 100644 (file)
@@ -2772,13 +2772,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
+                                               }
+                                       }
                                }
                        }
                }
index c8c918d36ba2f032649caca3df1d90d81cdbd9e4..448c7867a143ccb4d05872b7c2777e94bfbd3274 100644 (file)
@@ -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",
@@ -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 {