Skip to content

Commit eec9614

Browse files
committed
cmd/cgo, cmd/dist, cmd/go: cgo with clang fixes
1. Workaround the smart clang diagnostics with -Qunused-arguments: clang: error: argument unused during compilation: '-XXX' 2. if "clang -print-libgcc-file-name" returns non-absolute path, don't provide that on linker command line. 3. Fix dwarf.PtrType.Size() in cmd/cgo as clang doesn't generate DW_AT_byte_size for pointer types. 4. Workaround warnings for -Wno-unneeded-internal-declaration with -Wno-unknown-warning-option. 5. Add -Wno-unused-function. 6. enable race detector test on darwin with clang (at least Apple clang version 1.7 (tags/Apple/clang-77) works). Requires CL 7354043. Update #4829 This should fix most parts of the problem, but one glitch still remains. DWARF generated by newer clang doesn't differentiate these two function types: void *malloc(size_t); void *malloc(unsigned long int); so you might need to do this to make make.bash pass: sed -i -e 's/C.malloc(C.size_t/C.malloc(C.ulong/' pkg/os/user/lookup_unix.go R=golang-dev, dave, iant, rsc CC=golang-dev https://golang.org/cl/7351044
1 parent 1e957b6 commit eec9614

File tree

4 files changed

+43
-22
lines changed

4 files changed

+43
-22
lines changed

src/cmd/cgo/gcc.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -783,7 +783,13 @@ func (p *Package) gccCmd() []string {
783783
if strings.Contains(p.gccName(), "clang") {
784784
c = append(c,
785785
"-ferror-limit=0",
786+
// Apple clang version 1.7 (tags/Apple/clang-77) (based on LLVM 2.9svn)
787+
// doesn't have -Wno-unneeded-internal-declaration, so we need yet another
788+
// flag to disable the warning. Yes, really good diagnostics, clang.
789+
"-Wno-unknown-warning-option",
786790
"-Wno-unneeded-internal-declaration",
791+
"-Wno-unused-function",
792+
"-Qunused-arguments",
787793
)
788794
}
789795

@@ -1049,6 +1055,12 @@ func (c *typeConv) Type(dtype dwarf.Type, pos token.Pos) *Type {
10491055
return t
10501056
}
10511057

1058+
// clang won't generate DW_AT_byte_size for pointer types,
1059+
// so we have to fix it here.
1060+
if dt, ok := base(dtype).(*dwarf.PtrType); ok && dt.ByteSize == -1 {
1061+
dt.ByteSize = c.ptrSize
1062+
}
1063+
10521064
t := new(Type)
10531065
t.Size = dtype.Size()
10541066
t.Align = -1

src/cmd/dist/build.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -409,6 +409,7 @@ static char *proto_gccargs[] = {
409409
"-Wno-comment",
410410
"-Werror",
411411
"-fno-common",
412+
"-ggdb",
412413
"-pipe",
413414
"-O2",
414415
};
@@ -604,10 +605,10 @@ install(char *dir)
604605
splitfields(&gccargs, bstr(&b));
605606
for(i=0; i<nelem(proto_gccargs); i++)
606607
vadd(&gccargs, proto_gccargs[i]);
607-
if(clang)
608-
vadd(&gccargs, "-g");
609-
else
610-
vadd(&gccargs, "-ggdb");
608+
if(clang) {
609+
// clang is too smart about unused command-line arguments
610+
vadd(&gccargs, "-Qunused-arguments");
611+
}
611612
}
612613

613614
islib = hasprefix(dir, "lib") || streq(dir, "cmd/cc") || streq(dir, "cmd/gc");

src/cmd/go/build.go

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1609,6 +1609,8 @@ func gccgoCleanPkgpath(p *Package) string {
16091609
func (b *builder) libgcc(p *Package) (string, error) {
16101610
var buf bytes.Buffer
16111611

1612+
gccCmd := b.gccCmd(p.Dir)
1613+
16121614
prev := b.print
16131615
if buildN {
16141616
// In -n mode we temporarily swap out the builder's
@@ -1619,7 +1621,7 @@ func (b *builder) libgcc(p *Package) (string, error) {
16191621
return fmt.Fprint(&buf, a...)
16201622
}
16211623
}
1622-
f, err := b.runOut(p.Dir, p.ImportPath, b.gccCmd(p.Dir), "-print-libgcc-file-name")
1624+
f, err := b.runOut(p.Dir, p.ImportPath, gccCmd, "-print-libgcc-file-name")
16231625
if err != nil {
16241626
return "", fmt.Errorf("gcc -print-libgcc-file-name: %v (%s)", err, f)
16251627
}
@@ -1629,6 +1631,13 @@ func (b *builder) libgcc(p *Package) (string, error) {
16291631
b.print(s)
16301632
return "$LIBGCC", nil
16311633
}
1634+
1635+
// clang might not be able to find libgcc, and in that case,
1636+
// it will simply return "libgcc.a", which is of no use to us.
1637+
if strings.Contains(gccCmd[0], "clang") && !filepath.IsAbs(string(f)) {
1638+
return "", nil
1639+
}
1640+
16321641
return strings.Trim(string(f), "\r\n"), nil
16331642
}
16341643

@@ -1662,19 +1671,21 @@ func (b *builder) gccCmd(objdir string) []string {
16621671
}
16631672
a = append(a, b.gccArchArgs()...)
16641673
// gcc-4.5 and beyond require explicit "-pthread" flag
1665-
// for multithreading with pthread library, but clang whines
1666-
// about unused arguments if we pass it.
1674+
// for multithreading with pthread library.
16671675
if buildContext.CgoEnabled {
16681676
switch goos {
16691677
case "windows":
16701678
a = append(a, "-mthreads")
16711679
default:
1672-
if !strings.Contains(a[0], "clang") {
1673-
a = append(a, "-pthread")
1674-
}
1680+
a = append(a, "-pthread")
16751681
}
16761682
}
16771683

1684+
// clang is too smart about command-line arguments
1685+
if strings.Contains(a[0], "clang") {
1686+
a = append(a, "-Qunused-arguments")
1687+
}
1688+
16781689
// On OS X, some of the compilers behave as if -fno-common
16791690
// is always set, and the Mach-O linker in 6l/8l assumes this.
16801691
// See http://golang.org/issue/3253.
@@ -1706,6 +1717,7 @@ var cgoRe = regexp.MustCompile(`[/\\:]`)
17061717

17071718
var (
17081719
cgoLibGccFile string
1720+
cgoLibGccErr error
17091721
cgoLibGccFileOnce sync.Once
17101722
)
17111723

@@ -1800,21 +1812,19 @@ func (b *builder) cgo(p *Package, cgoExe, obj string, gccfiles []string) (outGo,
18001812
}
18011813

18021814
cgoLibGccFileOnce.Do(func() {
1803-
cgoLibGccFile, err = b.libgcc(p)
1815+
cgoLibGccFile, cgoLibGccErr = b.libgcc(p)
18041816
})
1805-
if cgoLibGccFile == "" {
1806-
if err == nil {
1807-
err = errors.New("failed to get libgcc filename")
1808-
}
1817+
if cgoLibGccFile == "" && cgoLibGccErr != nil {
18091818
return nil, nil, err
18101819
}
18111820

18121821
var staticLibs []string
18131822
if goos == "windows" {
18141823
// libmingw32 and libmingwex might also use libgcc, so libgcc must come last
1815-
staticLibs = []string{"-lmingwex", "-lmingw32", cgoLibGccFile}
1816-
} else {
1817-
staticLibs = []string{cgoLibGccFile}
1824+
staticLibs = []string{"-lmingwex", "-lmingw32"}
1825+
}
1826+
if cgoLibGccFile != "" {
1827+
staticLibs = append(staticLibs, cgoLibGccFile)
18181828
}
18191829

18201830
for _, cfile := range cfiles {

src/run.bash

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,8 @@ go test sync -short -timeout=120s -cpu=10
4848

4949
# Race detector only supported on Linux and OS X,
5050
# and only on amd64, and only when cgo is enabled.
51-
# Also, clang can't seem to link the .syso files, so only
52-
# run if we're using gcc.
53-
case "$GOHOSTOS-$GOOS-$GOARCH-$CGO_ENABLED-${CC:-gcc}" in
54-
linux-linux-amd64-1-*gcc* | darwin-darwin-amd64-1-*gcc*)
51+
case "$GOHOSTOS-$GOOS-$GOARCH-$CGO_ENABLED" in
52+
linux-linux-amd64-1 | darwin-darwin-amd64-1)
5553
echo
5654
echo '# Testing race detector.'
5755
go test -race -i flag

0 commit comments

Comments
 (0)