]> Cypherpunks repositories - gostls13.git/commitdiff
misc/cgo/test: do not redeclare exported Go functions
authorRuss Cox <rsc@golang.org>
Tue, 20 Apr 2021 17:30:50 +0000 (13:30 -0400)
committerRuss Cox <rsc@golang.org>
Fri, 23 Apr 2021 21:42:52 +0000 (21:42 +0000)
An exported Go function like

//export F
func F() {}

gets declared in _cgo_export.h as something like

extern void F(void);

The exact declaration varies by operating system.
In particular, Windows adds __declspec(dllimport).

Clang on Windows/ARM64 rejects code that contains
conflicting declarations for F, like:

extern void F(void);
extern void __declspec(dllimport) F(void);

This means that F must not be declared separately from _cgo_export.h:
any code that wants to refer to F must use #include "_cgo_export.h".

Unfortunately, the cgo prologue itself (the commented code before import "C")
cannot include "_cgo_export.h", because that file is itself produced from the
cgo Go sources and therefore cannot be a dependency of the cgo Go sources.

This CL rewrites misc/cgo/test to avoid redeclaring exported functions.
Most of the time, this is not a significant problem: just move the code
that needs the header into a .c file, perhaps with a wrapper exposed
to the cgo Go sources.

The one case that is potentially problematic is f7665, which is part of
the test for golang.org/issue/7665. That bug report explicitly identified
a bug in referring to the C name for an exported function in the same
Go source file as it was exported function. That is now impossible,
at least on Windows/ARM64, so the test is modified a bit and possibly
does not test what the original bug was. But the original bug should
be long gone: that part of the compiler has been rewritten.

Change-Id: I0d14d9336632f0e5e3db4273d9d32ef2cca0298d
Reviewed-on: https://go-review.googlesource.com/c/go/+/312029
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
misc/cgo/test/issue8148.c [new file with mode: 0644]
misc/cgo/test/issue8148.go
misc/cgo/test/testx.c [new file with mode: 0644]
misc/cgo/test/testx.go

diff --git a/misc/cgo/test/issue8148.c b/misc/cgo/test/issue8148.c
new file mode 100644 (file)
index 0000000..927b434
--- /dev/null
@@ -0,0 +1,11 @@
+// Copyright 2014 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.
+
+#include "_cgo_export.h"
+
+int get8148(void) {
+       T t;
+       t.i = 42;
+       return issue8148Callback(&t);
+}
index f704788aef8a45da1d8d195f8c478ee7d617f3e5..aee9003d5075bf02751a477e9fc7ffb8da2d4009 100644 (file)
@@ -10,14 +10,7 @@ package cgotest
 
 /*
 typedef struct { int i; } T;
-
-int issue8148Callback(T*);
-
-static int get() {
-       T t;
-       t.i = 42;
-       return issue8148Callback(&t);
-}
+int get8148(void);
 */
 import "C"
 
@@ -27,5 +20,5 @@ func issue8148Callback(t *C.T) C.int {
 }
 
 func Issue8148() int {
-       return int(C.get())
+       return int(C.get8148())
 }
diff --git a/misc/cgo/test/testx.c b/misc/cgo/test/testx.c
new file mode 100644 (file)
index 0000000..1258e32
--- /dev/null
@@ -0,0 +1,24 @@
+// Copyright 2021 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.
+
+#include "_cgo_export.h"
+
+void lockOSThreadC(void) {
+       lockOSThreadCallback();
+}
+
+void issue7978c(uint32_t *sync) {
+       while(__atomic_load_n(sync, __ATOMIC_SEQ_CST) != 0)
+               ;
+       __atomic_add_fetch(sync, 1, __ATOMIC_SEQ_CST);
+       while(__atomic_load_n(sync, __ATOMIC_SEQ_CST) != 2)
+               ;
+       issue7978cb();
+       __atomic_add_fetch(sync, 1, __ATOMIC_SEQ_CST);
+       while(__atomic_load_n(sync, __ATOMIC_SEQ_CST) != 6)
+               ;
+}
+
+void f7665(void) {
+}
index 044c5bceff5eb2cb1b7a37d03c4d7a8228c79906..823c3e13d2927aac7bfd240ddd46b69882a8aff0 100644 (file)
@@ -27,7 +27,6 @@ import (
 extern void doAdd(int, int);
 
 // issue 1328
-extern void BackIntoGo(void);
 void IntoC(void);
 
 // issue 1560
@@ -39,11 +38,7 @@ long long mysleep(int seconds);
 long long twoSleep(int);
 
 // issue 3775
-void lockOSThreadCallback(void);
-inline static void lockOSThreadC(void)
-{
-        lockOSThreadCallback();
-}
+void lockOSThreadC(void);
 int usleep(unsigned usec);
 
 // issue 4054 part 2 - part 1 in test.go
@@ -82,21 +77,9 @@ extern void f7665(void);
 
 #include <stdint.h>
 
-void issue7978cb(void);
-
 // use ugly atomic variable sync since that doesn't require calling back into
 // Go code or OS dependencies
-static void issue7978c(uint32_t *sync) {
-       while(__atomic_load_n(sync, __ATOMIC_SEQ_CST) != 0)
-               ;
-       __atomic_add_fetch(sync, 1, __ATOMIC_SEQ_CST);
-       while(__atomic_load_n(sync, __ATOMIC_SEQ_CST) != 2)
-               ;
-       issue7978cb();
-       __atomic_add_fetch(sync, 1, __ATOMIC_SEQ_CST);
-       while(__atomic_load_n(sync, __ATOMIC_SEQ_CST) != 6)
-               ;
-}
+void issue7978c(uint32_t *sync);
 
 // issue 8331 part 2 - part 1 in test.go
 // A typedef of an unnamed struct is the same struct when
@@ -429,9 +412,6 @@ func test6907Go(t *testing.T) {
 
 // issue 7665
 
-//export f7665
-func f7665() {}
-
 var bad7665 unsafe.Pointer = C.f7665
 var good7665 uintptr = uintptr(C.f7665)