Commit eec96147 authored by Shenghou Ma's avatar Shenghou Ma

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
parent 1e957b62
......@@ -783,7 +783,13 @@ func (p *Package) gccCmd() []string {
if strings.Contains(p.gccName(), "clang") {
c = append(c,
"-ferror-limit=0",
// Apple clang version 1.7 (tags/Apple/clang-77) (based on LLVM 2.9svn)
// doesn't have -Wno-unneeded-internal-declaration, so we need yet another
// flag to disable the warning. Yes, really good diagnostics, clang.
"-Wno-unknown-warning-option",
"-Wno-unneeded-internal-declaration",
"-Wno-unused-function",
"-Qunused-arguments",
)
}
......@@ -1049,6 +1055,12 @@ func (c *typeConv) Type(dtype dwarf.Type, pos token.Pos) *Type {
return t
}
// clang won't generate DW_AT_byte_size for pointer types,
// so we have to fix it here.
if dt, ok := base(dtype).(*dwarf.PtrType); ok && dt.ByteSize == -1 {
dt.ByteSize = c.ptrSize
}
t := new(Type)
t.Size = dtype.Size()
t.Align = -1
......
......@@ -409,6 +409,7 @@ static char *proto_gccargs[] = {
"-Wno-comment",
"-Werror",
"-fno-common",
"-ggdb",
"-pipe",
"-O2",
};
......@@ -604,10 +605,10 @@ install(char *dir)
splitfields(&gccargs, bstr(&b));
for(i=0; i<nelem(proto_gccargs); i++)
vadd(&gccargs, proto_gccargs[i]);
if(clang)
vadd(&gccargs, "-g");
else
vadd(&gccargs, "-ggdb");
if(clang) {
// clang is too smart about unused command-line arguments
vadd(&gccargs, "-Qunused-arguments");
}
}
islib = hasprefix(dir, "lib") || streq(dir, "cmd/cc") || streq(dir, "cmd/gc");
......
......@@ -1609,6 +1609,8 @@ func gccgoCleanPkgpath(p *Package) string {
func (b *builder) libgcc(p *Package) (string, error) {
var buf bytes.Buffer
gccCmd := b.gccCmd(p.Dir)
prev := b.print
if buildN {
// In -n mode we temporarily swap out the builder's
......@@ -1619,7 +1621,7 @@ func (b *builder) libgcc(p *Package) (string, error) {
return fmt.Fprint(&buf, a...)
}
}
f, err := b.runOut(p.Dir, p.ImportPath, b.gccCmd(p.Dir), "-print-libgcc-file-name")
f, err := b.runOut(p.Dir, p.ImportPath, gccCmd, "-print-libgcc-file-name")
if err != nil {
return "", fmt.Errorf("gcc -print-libgcc-file-name: %v (%s)", err, f)
}
......@@ -1629,6 +1631,13 @@ func (b *builder) libgcc(p *Package) (string, error) {
b.print(s)
return "$LIBGCC", nil
}
// clang might not be able to find libgcc, and in that case,
// it will simply return "libgcc.a", which is of no use to us.
if strings.Contains(gccCmd[0], "clang") && !filepath.IsAbs(string(f)) {
return "", nil
}
return strings.Trim(string(f), "\r\n"), nil
}
......@@ -1662,19 +1671,21 @@ func (b *builder) gccCmd(objdir string) []string {
}
a = append(a, b.gccArchArgs()...)
// gcc-4.5 and beyond require explicit "-pthread" flag
// for multithreading with pthread library, but clang whines
// about unused arguments if we pass it.
// for multithreading with pthread library.
if buildContext.CgoEnabled {
switch goos {
case "windows":
a = append(a, "-mthreads")
default:
if !strings.Contains(a[0], "clang") {
a = append(a, "-pthread")
}
a = append(a, "-pthread")
}
}
// clang is too smart about command-line arguments
if strings.Contains(a[0], "clang") {
a = append(a, "-Qunused-arguments")
}
// On OS X, some of the compilers behave as if -fno-common
// is always set, and the Mach-O linker in 6l/8l assumes this.
// See http://golang.org/issue/3253.
......@@ -1706,6 +1717,7 @@ var cgoRe = regexp.MustCompile(`[/\\:]`)
var (
cgoLibGccFile string
cgoLibGccErr error
cgoLibGccFileOnce sync.Once
)
......@@ -1800,21 +1812,19 @@ func (b *builder) cgo(p *Package, cgoExe, obj string, gccfiles []string) (outGo,
}
cgoLibGccFileOnce.Do(func() {
cgoLibGccFile, err = b.libgcc(p)
cgoLibGccFile, cgoLibGccErr = b.libgcc(p)
})
if cgoLibGccFile == "" {
if err == nil {
err = errors.New("failed to get libgcc filename")
}
if cgoLibGccFile == "" && cgoLibGccErr != nil {
return nil, nil, err
}
var staticLibs []string
if goos == "windows" {
// libmingw32 and libmingwex might also use libgcc, so libgcc must come last
staticLibs = []string{"-lmingwex", "-lmingw32", cgoLibGccFile}
} else {
staticLibs = []string{cgoLibGccFile}
staticLibs = []string{"-lmingwex", "-lmingw32"}
}
if cgoLibGccFile != "" {
staticLibs = append(staticLibs, cgoLibGccFile)
}
for _, cfile := range cfiles {
......
......@@ -48,10 +48,8 @@ go test sync -short -timeout=120s -cpu=10
# Race detector only supported on Linux and OS X,
# and only on amd64, and only when cgo is enabled.
# Also, clang can't seem to link the .syso files, so only
# run if we're using gcc.
case "$GOHOSTOS-$GOOS-$GOARCH-$CGO_ENABLED-${CC:-gcc}" in
linux-linux-amd64-1-*gcc* | darwin-darwin-amd64-1-*gcc*)
case "$GOHOSTOS-$GOOS-$GOARCH-$CGO_ENABLED" in
linux-linux-amd64-1 | darwin-darwin-amd64-1)
echo
echo '# Testing race detector.'
go test -race -i flag
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment