]> Cypherpunks repositories - gostls13.git/commitdiff
cgo: print line numbers in fatal errors when relevant.
authorRémy Oudompheng <oudomphe@phare.normalesup.org>
Mon, 6 Feb 2012 19:38:54 +0000 (20:38 +0100)
committerRémy Oudompheng <oudomphe@phare.normalesup.org>
Mon, 6 Feb 2012 19:38:54 +0000 (20:38 +0100)
Signatures of fatalf and error_ helpers have been matched for
consistency.
Fixes #1800.

R=rsc
CC=golang-dev, remy
https://golang.org/cl/5593049

src/cmd/cgo/gcc.go
src/cmd/cgo/util.go
test/fixedbugs/bug408.go [new file with mode: 0644]

index 155eb0440f944626944edca56bbbe39d3f6e2e4a..71a9457f5f750dd7105575233882d3c60a5333d2 100644 (file)
@@ -524,6 +524,10 @@ func (p *Package) loadDWARF(f *File, names []*Name) {
        for i, n := range names {
                nameToIndex[n] = i
        }
+       nameToRef := make(map[*Name]*Ref)
+       for _, ref := range f.Ref {
+               nameToRef[ref.Name] = ref
+       }
        r := d.Reader()
        for {
                e, err := r.Next()
@@ -597,12 +601,16 @@ func (p *Package) loadDWARF(f *File, names []*Name) {
                if types[i] == nil {
                        continue
                }
+               pos := token.NoPos
+               if ref, ok := nameToRef[n]; ok {
+                       pos = ref.Pos()
+               }
                f, fok := types[i].(*dwarf.FuncType)
                if n.Kind != "type" && fok {
                        n.Kind = "func"
-                       n.FuncType = conv.FuncType(f)
+                       n.FuncType = conv.FuncType(f, pos)
                } else {
-                       n.Type = conv.Type(types[i])
+                       n.Type = conv.Type(types[i], pos)
                        if enums[i] != 0 && n.Type.EnumValues != nil {
                                k := fmt.Sprintf("__cgo_enum__%d", i)
                                n.Kind = "const"
@@ -972,10 +980,10 @@ func (tr *TypeRepr) Set(repr string, fargs ...interface{}) {
 
 // Type returns a *Type with the same memory layout as
 // dtype when used as the type of a variable or a struct field.
-func (c *typeConv) Type(dtype dwarf.Type) *Type {
+func (c *typeConv) Type(dtype dwarf.Type, pos token.Pos) *Type {
        if t, ok := c.m[dtype]; ok {
                if t.Go == nil {
-                       fatalf("type conversion loop at %s", dtype)
+                       fatalf("%s: type conversion loop at %s", lineno(pos), dtype)
                }
                return t
        }
@@ -998,11 +1006,11 @@ func (c *typeConv) Type(dtype dwarf.Type) *Type {
 
        switch dt := dtype.(type) {
        default:
-               fatalf("unexpected type: %s", dtype)
+               fatalf("%s: unexpected type: %s", lineno(pos), dtype)
 
        case *dwarf.AddrType:
                if t.Size != c.ptrSize {
-                       fatalf("unexpected: %d-byte address type - %s", t.Size, dtype)
+                       fatalf("%s: unexpected: %d-byte address type - %s", lineno(pos), t.Size, dtype)
                }
                t.Go = c.uintptr
                t.Align = t.Size
@@ -1017,7 +1025,7 @@ func (c *typeConv) Type(dtype dwarf.Type) *Type {
                        Len: c.intExpr(dt.Count),
                }
                t.Go = gt // publish before recursive call
-               sub := c.Type(dt.Type)
+               sub := c.Type(dt.Type, pos)
                t.Align = sub.Align
                gt.Elt = sub.Go
                t.C.Set("typeof(%s[%d])", sub.C, dt.Count)
@@ -1028,7 +1036,7 @@ func (c *typeConv) Type(dtype dwarf.Type) *Type {
 
        case *dwarf.CharType:
                if t.Size != 1 {
-                       fatalf("unexpected: %d-byte char type - %s", t.Size, dtype)
+                       fatalf("%s: unexpected: %d-byte char type - %s", lineno(pos), t.Size, dtype)
                }
                t.Go = c.int8
                t.Align = 1
@@ -1048,7 +1056,7 @@ func (c *typeConv) Type(dtype dwarf.Type) *Type {
                }
                switch t.Size + int64(signed) {
                default:
-                       fatalf("unexpected: %d-byte enum type - %s", t.Size, dtype)
+                       fatalf("%s: unexpected: %d-byte enum type - %s", lineno(pos), t.Size, dtype)
                case 1:
                        t.Go = c.uint8
                case 2:
@@ -1070,7 +1078,7 @@ func (c *typeConv) Type(dtype dwarf.Type) *Type {
        case *dwarf.FloatType:
                switch t.Size {
                default:
-                       fatalf("unexpected: %d-byte float type - %s", t.Size, dtype)
+                       fatalf("%s: unexpected: %d-byte float type - %s", lineno(pos), t.Size, dtype)
                case 4:
                        t.Go = c.float32
                case 8:
@@ -1083,7 +1091,7 @@ func (c *typeConv) Type(dtype dwarf.Type) *Type {
        case *dwarf.ComplexType:
                switch t.Size {
                default:
-                       fatalf("unexpected: %d-byte complex type - %s", t.Size, dtype)
+                       fatalf("%s: unexpected: %d-byte complex type - %s", lineno(pos), t.Size, dtype)
                case 8:
                        t.Go = c.complex64
                case 16:
@@ -1101,11 +1109,11 @@ func (c *typeConv) Type(dtype dwarf.Type) *Type {
 
        case *dwarf.IntType:
                if dt.BitSize > 0 {
-                       fatalf("unexpected: %d-bit int type - %s", dt.BitSize, dtype)
+                       fatalf("%s: unexpected: %d-bit int type - %s", lineno(pos), dt.BitSize, dtype)
                }
                switch t.Size {
                default:
-                       fatalf("unexpected: %d-byte int type - %s", t.Size, dtype)
+                       fatalf("%s: unexpected: %d-byte int type - %s", lineno(pos), t.Size, dtype)
                case 1:
                        t.Go = c.int8
                case 2:
@@ -1131,13 +1139,13 @@ func (c *typeConv) Type(dtype dwarf.Type) *Type {
 
                gt := &ast.StarExpr{}
                t.Go = gt // publish before recursive call
-               sub := c.Type(dt.Type)
+               sub := c.Type(dt.Type, pos)
                gt.X = sub.Go
                t.C.Set("%s*", sub.C)
 
        case *dwarf.QualType:
                // Ignore qualifier.
-               t = c.Type(dt.Type)
+               t = c.Type(dt.Type, pos)
                c.m[dtype] = t
                return t
 
@@ -1161,7 +1169,7 @@ func (c *typeConv) Type(dtype dwarf.Type) *Type {
                                t.C.Set("typeof(unsigned char[%d])", t.Size)
                        }
                case "struct":
-                       g, csyntax, align := c.Struct(dt)
+                       g, csyntax, align := c.Struct(dt, pos)
                        if t.C.Empty() {
                                t.C.Set(csyntax)
                        }
@@ -1191,7 +1199,7 @@ func (c *typeConv) Type(dtype dwarf.Type) *Type {
                name := c.Ident("_Ctype_" + dt.Name)
                goIdent[name.Name] = name
                t.Go = name // publish before recursive call
-               sub := c.Type(dt.Type)
+               sub := c.Type(dt.Type, pos)
                t.Size = sub.Size
                t.Align = sub.Align
                if _, ok := typedef[name.Name]; !ok {
@@ -1203,18 +1211,18 @@ func (c *typeConv) Type(dtype dwarf.Type) *Type {
 
        case *dwarf.UcharType:
                if t.Size != 1 {
-                       fatalf("unexpected: %d-byte uchar type - %s", t.Size, dtype)
+                       fatalf("%s: unexpected: %d-byte uchar type - %s", lineno(pos), t.Size, dtype)
                }
                t.Go = c.uint8
                t.Align = 1
 
        case *dwarf.UintType:
                if dt.BitSize > 0 {
-                       fatalf("unexpected: %d-bit uint type - %s", dt.BitSize, dtype)
+                       fatalf("%s: unexpected: %d-bit uint type - %s", lineno(pos), dt.BitSize, dtype)
                }
                switch t.Size {
                default:
-                       fatalf("unexpected: %d-byte uint type - %s", t.Size, dtype)
+                       fatalf("%s: unexpected: %d-byte uint type - %s", lineno(pos), t.Size, dtype)
                case 1:
                        t.Go = c.uint8
                case 2:
@@ -1250,7 +1258,7 @@ func (c *typeConv) Type(dtype dwarf.Type) *Type {
        }
 
        if t.C.Empty() {
-               fatalf("internal error: did not create C name for %s", dtype)
+               fatalf("%s: internal error: did not create C name for %s", lineno(pos), dtype)
        }
 
        return t
@@ -1258,8 +1266,8 @@ func (c *typeConv) Type(dtype dwarf.Type) *Type {
 
 // FuncArg returns a Go type with the same memory layout as
 // dtype when used as the type of a C function argument.
-func (c *typeConv) FuncArg(dtype dwarf.Type) *Type {
-       t := c.Type(dtype)
+func (c *typeConv) FuncArg(dtype dwarf.Type, pos token.Pos) *Type {
+       t := c.Type(dtype, pos)
        switch dt := dtype.(type) {
        case *dwarf.ArrayType:
                // Arrays are passed implicitly as pointers in C.
@@ -1281,7 +1289,7 @@ func (c *typeConv) FuncArg(dtype dwarf.Type) *Type {
                        // Unless the typedef happens to point to void* since
                        // Go has special rules around using unsafe.Pointer.
                        if _, void := base(ptr.Type).(*dwarf.VoidType); !void {
-                               return c.Type(ptr)
+                               return c.Type(ptr, pos)
                        }
                }
        }
@@ -1290,7 +1298,7 @@ func (c *typeConv) FuncArg(dtype dwarf.Type) *Type {
 
 // FuncType returns the Go type analogous to dtype.
 // There is no guarantee about matching memory layout.
-func (c *typeConv) FuncType(dtype *dwarf.FuncType) *FuncType {
+func (c *typeConv) FuncType(dtype *dwarf.FuncType, pos token.Pos) *FuncType {
        p := make([]*Type, len(dtype.ParamType))
        gp := make([]*ast.Field, len(dtype.ParamType))
        for i, f := range dtype.ParamType {
@@ -1303,13 +1311,13 @@ func (c *typeConv) FuncType(dtype *dwarf.FuncType) *FuncType {
                        p, gp = nil, nil
                        break
                }
-               p[i] = c.FuncArg(f)
+               p[i] = c.FuncArg(f, pos)
                gp[i] = &ast.Field{Type: p[i].Go}
        }
        var r *Type
        var gr []*ast.Field
        if _, ok := dtype.ReturnType.(*dwarf.VoidType); !ok && dtype.ReturnType != nil {
-               r = c.Type(dtype.ReturnType)
+               r = c.Type(dtype.ReturnType, pos)
                gr = []*ast.Field{{Type: r.Go}}
        }
        return &FuncType{
@@ -1352,7 +1360,7 @@ func (c *typeConv) pad(fld []*ast.Field, size int64) []*ast.Field {
 }
 
 // Struct conversion: return Go and (6g) C syntax for type.
-func (c *typeConv) Struct(dt *dwarf.StructType) (expr *ast.StructType, csyntax string, align int64) {
+func (c *typeConv) Struct(dt *dwarf.StructType, pos token.Pos) (expr *ast.StructType, csyntax string, align int64) {
        var buf bytes.Buffer
        buf.WriteString("struct {")
        fld := make([]*ast.Field, 0, 2*len(dt.Field)+1) // enough for padding around every field
@@ -1394,7 +1402,7 @@ func (c *typeConv) Struct(dt *dwarf.StructType) (expr *ast.StructType, csyntax s
                        fld = c.pad(fld, f.ByteOffset-off)
                        off = f.ByteOffset
                }
-               t := c.Type(f.Type)
+               t := c.Type(f.Type, pos)
                tgo := t.Go
                size := t.Size
 
@@ -1435,7 +1443,7 @@ func (c *typeConv) Struct(dt *dwarf.StructType) (expr *ast.StructType, csyntax s
                off = dt.ByteSize
        }
        if off != dt.ByteSize {
-               fatalf("struct size calculation error")
+               fatalf("%s: struct size calculation error", lineno(pos))
        }
        buf.WriteString("}")
        csyntax = buf.String()
index 8a778418df619720e3051ecb57939f31359069d7..1bf665ff4757dbb8a1bcb423c79f2d1fb26714d2 100644 (file)
@@ -64,6 +64,10 @@ func run(stdin []byte, argv []string) (stdout, stderr []byte, ok bool) {
        return
 }
 
+func lineno(pos token.Pos) string {
+       return fset.Position(pos).String()
+}
+
 // Die with an error message.
 func fatalf(msg string, args ...interface{}) {
        fmt.Fprintf(os.Stderr, msg+"\n", args...)
diff --git a/test/fixedbugs/bug408.go b/test/fixedbugs/bug408.go
new file mode 100644 (file)
index 0000000..421b80d
--- /dev/null
@@ -0,0 +1,16 @@
+// errchk cgo $D/$F.go
+
+// Copyright 2012 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.
+
+// Issue 1800: cgo not reporting line numbers.
+
+package main
+
+// #include <stdio.h>
+import "C"
+
+func f() {
+       C.printf(nil) // ERROR "go:15.*unexpected type"
+}