Skip to content

Commit 2fdff95

Browse files
cmd/go: always use --whole-archive for gccgo packages
This is, in effect, what the gc toolchain does. It fixes cases where Go code refers to a C global variable; without this, if the global variable was the only thing visible in the C code, the generated cgo file might not get pulled in from the archive, leaving the Go variable uninitialized. This was reported against gccgo as https://gcc.gnu.org/PR68255 . Change-Id: I3e769dd174f64050ebbff268fbbf5e6fab1e2a1b Reviewed-on: https://go-review.googlesource.com/16775 Run-TryBot: Ian Lance Taylor <[email protected]> Reviewed-by: Russ Cox <[email protected]>
1 parent 07a6cbf commit 2fdff95

6 files changed

Lines changed: 50 additions & 10 deletions

File tree

misc/cgo/test/cgo_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,5 +66,6 @@ func Test9557(t *testing.T) { test9557(t) }
6666
func Test10303(t *testing.T) { test10303(t, 10) }
6767
func Test11925(t *testing.T) { test11925(t) }
6868
func Test12030(t *testing.T) { test12030(t) }
69+
func TestGCC68255(t *testing.T) { testGCC68255(t) }
6970

7071
func BenchmarkCgoCall(b *testing.B) { benchCgoCall(b) }

misc/cgo/test/gcc68255.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// Copyright 2015 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+
"./gcc68255"
11+
)
12+
13+
func testGCC68255(t *testing.T) {
14+
if !gcc68255.F() {
15+
t.Error("C global variable was not initialized")
16+
}
17+
}

misc/cgo/test/gcc68255/a.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// Copyright 2015 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+
// Test that it's OK to have C code that does nothing other than
6+
// initialize a global variable. This used to fail with gccgo.
7+
8+
package gcc68255
9+
10+
/*
11+
#include "c.h"
12+
*/
13+
import "C"
14+
15+
func F() bool {
16+
return C.v != nil
17+
}

misc/cgo/test/gcc68255/c.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// Copyright 2015 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+
static void f(void) {
6+
}
7+
8+
void (*v)(void) = f;

misc/cgo/test/gcc68255/c.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// Copyright 2015 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+
extern void (*v)(void);

src/cmd/go/build.go

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2599,17 +2599,9 @@ func (tools gccgoToolchain) ld(b *builder, root *action, out string, allactions
25992599
}
26002600
}
26012601

2602-
switch ldBuildmode {
2603-
case "c-archive", "c-shared":
2604-
ldflags = append(ldflags, "-Wl,--whole-archive")
2605-
}
2606-
2602+
ldflags = append(ldflags, "-Wl,--whole-archive")
26072603
ldflags = append(ldflags, afiles...)
2608-
2609-
switch ldBuildmode {
2610-
case "c-archive", "c-shared":
2611-
ldflags = append(ldflags, "-Wl,--no-whole-archive")
2612-
}
2604+
ldflags = append(ldflags, "-Wl,--no-whole-archive")
26132605

26142606
ldflags = append(ldflags, cgoldflags...)
26152607
ldflags = append(ldflags, envList("CGO_LDFLAGS", "")...)

0 commit comments

Comments
 (0)