Skip to content

Commit fce06f5

Browse files
committed
cmd/cgo: Define exported Go func as function
In order to resolve symbols correctly during C compilation with CGO the compiler emits a _cgo_main.c file which holds definitions for symbols. The problem is that the definitions in the _cgo_main.c do not match up with what's declared in _cgo_export.c which causes compilation to fail if using CGO_CFLAGS="-flto -ffat-lto-objects" due to an incompatibility with link time optimization in GCC. This patch makes it so that the symbol emitted in _cgo_main.c lines up with the type declared in _cgo_export.c. This should be safe to do as the actual exported C symbol ends up as an argument to crosscall2 which defines the function signature for these exported symbols. The function sig will be consistent in that way since CGO generates wrappers and structs to handle argument / return value passing.
1 parent 2f0da6d commit fce06f5

File tree

2 files changed

+35
-1
lines changed

2 files changed

+35
-1
lines changed

src/cmd/cgo/out.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1028,7 +1028,7 @@ func (p *Package) writeExports(fgo2, fm, fgcc, fgcch io.Writer) {
10281028
fmt.Fprintf(fgo2, "//go:cgo_export_static _cgoexp%s_%s\n", cPrefix, exp.ExpName)
10291029
fmt.Fprintf(fgo2, "func _cgoexp%s_%s(a *%s) {\n", cPrefix, exp.ExpName, gotype)
10301030

1031-
fmt.Fprintf(fm, "int _cgoexp%s_%s;\n", cPrefix, exp.ExpName)
1031+
fmt.Fprintf(fm, "void _cgoexp%s_%s(void* p){};\n", cPrefix, exp.ExpName)
10321032

10331033
if gccResult != "void" {
10341034
// Write results back to frame.
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# tests golang.org/issue/43830
2+
3+
[!cgo] skip
4+
5+
env CGO_CFLAGS='-flto -ffat-lto-objects'
6+
go build main.go add.go
7+
8+
-- main.go --
9+
10+
package main
11+
12+
/*
13+
int c_add(int a, int b) {
14+
return myadd(a, b);
15+
}
16+
*/
17+
import "C"
18+
19+
func main() {
20+
println(C.c_add(1, 2))
21+
}
22+
23+
-- add.go --
24+
25+
package main
26+
27+
import "C"
28+
29+
/* test */
30+
31+
//export myadd
32+
func myadd(a C.int, b C.int) C.int {
33+
return a + b
34+
}

0 commit comments

Comments
 (0)