]> Cypherpunks.ru repositories - gostls13.git/commitdiff
cmd/cgo: add and use runtime/cgo.Incomplete instead of //go:notinheap
authorCuong Manh Le <cuong.manhle.vn@gmail.com>
Sun, 7 Aug 2022 11:41:42 +0000 (18:41 +0700)
committerCuong Manh Le <cuong.manhle.vn@gmail.com>
Sun, 28 Aug 2022 16:04:49 +0000 (16:04 +0000)
Updates #46731

Change-Id: Ia83f27c177cc2f57e240cb5c6708d4552423f5be
Reviewed-on: https://go-review.googlesource.com/c/go/+/421879
Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: Keith Randall <khr@golang.org>
Reviewed-by: David Chase <drchase@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>

api/next/46731.txt [new file with mode: 0644]
src/cmd/cgo/gcc.go
src/cmd/cgo/main.go
src/cmd/cgo/out.go
src/runtime/cgo/cgo.go

diff --git a/api/next/46731.txt b/api/next/46731.txt
new file mode 100644 (file)
index 0000000..1d491ef
--- /dev/null
@@ -0,0 +1,14 @@
+pkg runtime/cgo (darwin-amd64-cgo), type Incomplete struct #46731
+pkg runtime/cgo (freebsd-386-cgo), type Incomplete struct #46731
+pkg runtime/cgo (freebsd-amd64-cgo), type Incomplete struct #46731
+pkg runtime/cgo (freebsd-arm-cgo), type Incomplete struct #46731
+pkg runtime/cgo (linux-386-cgo), type Incomplete struct #46731
+pkg runtime/cgo (linux-amd64-cgo), type Incomplete struct #46731
+pkg runtime/cgo (linux-arm-cgo), type Incomplete struct #46731
+pkg runtime/cgo (netbsd-386-cgo), type Incomplete struct #46731
+pkg runtime/cgo (netbsd-amd64-cgo), type Incomplete struct #46731
+pkg runtime/cgo (netbsd-arm-cgo), type Incomplete struct #46731
+pkg runtime/cgo (netbsd-arm64-cgo), type Incomplete struct #46731
+pkg runtime/cgo (openbsd-386-cgo), type Incomplete struct #46731
+pkg runtime/cgo (openbsd-amd64-cgo), type Incomplete struct #46731
+pkg runtime/cgo, type Incomplete struct #46731
index d89bff287b32797a6a293da0e833e594f1b780f8..43f94bb0e53b65009834817602151d0b13f3d31c 100644 (file)
@@ -2154,8 +2154,8 @@ type typeConv struct {
        // Type names X for which there exists an XGetTypeID function with type func() CFTypeID.
        getTypeIDs map[string]bool
 
-       // badStructs contains C structs that should be marked NotInHeap.
-       notInHeapStructs map[string]bool
+       // incompleteStructs contains C structs that should be marked Incomplete.
+       incompleteStructs map[string]bool
 
        // Predeclared types.
        bool                                   ast.Expr
@@ -2168,7 +2168,6 @@ type typeConv struct {
        string                                 ast.Expr
        goVoid                                 ast.Expr // _Ctype_void, denotes C's void
        goVoidPtr                              ast.Expr // unsafe.Pointer or *byte
-       goVoidPtrNoHeap                        ast.Expr // *_Ctype_void_notinheap, like goVoidPtr but marked NotInHeap
 
        ptrSize int64
        intSize int64
@@ -2192,7 +2191,7 @@ func (c *typeConv) Init(ptrSize, intSize int64) {
        c.m = make(map[string]*Type)
        c.ptrs = make(map[string][]*Type)
        c.getTypeIDs = make(map[string]bool)
-       c.notInHeapStructs = make(map[string]bool)
+       c.incompleteStructs = make(map[string]bool)
        c.bool = c.Ident("bool")
        c.byte = c.Ident("byte")
        c.int8 = c.Ident("int8")
@@ -2211,7 +2210,6 @@ func (c *typeConv) Init(ptrSize, intSize int64) {
        c.void = c.Ident("void")
        c.string = c.Ident("string")
        c.goVoid = c.Ident("_Ctype_void")
-       c.goVoidPtrNoHeap = c.Ident("*_Ctype_void_notinheap")
 
        // Normally cgo translates void* to unsafe.Pointer,
        // but for historical reasons -godefs uses *byte instead.
@@ -2561,19 +2559,13 @@ func (c *typeConv) loadType(dtype dwarf.Type, pos token.Pos, parent string) *Typ
                        // other than try to determine a Go representation.
                        tt := *t
                        tt.C = &TypeRepr{"%s %s", []interface{}{dt.Kind, tag}}
-                       tt.Go = c.Ident("struct{}")
-                       if dt.Kind == "struct" {
-                               // We don't know what the representation of this struct is, so don't let
-                               // anyone allocate one on the Go side. As a side effect of this annotation,
-                               // pointers to this type will not be considered pointers in Go. They won't
-                               // get writebarrier-ed or adjusted during a stack copy. This should handle
-                               // all the cases badPointerTypedef used to handle, but hopefully will
-                               // continue to work going forward without any more need for cgo changes.
-                               tt.NotInHeap = true
-                               // TODO: we should probably do the same for unions. Unions can't live
-                               // on the Go heap, right? It currently doesn't work for unions because
-                               // they are defined as a type alias for struct{}, not a defined type.
-                       }
+                       // We don't know what the representation of this struct is, so don't let
+                       // anyone allocate one on the Go side. As a side effect of this annotation,
+                       // pointers to this type will not be considered pointers in Go. They won't
+                       // get writebarrier-ed or adjusted during a stack copy. This should handle
+                       // all the cases badPointerTypedef used to handle, but hopefully will
+                       // continue to work going forward without any more need for cgo changes.
+                       tt.Go = c.Ident("_cgopackage.Incomplete")
                        typedef[name.Name] = &tt
                        break
                }
@@ -2599,7 +2591,9 @@ func (c *typeConv) loadType(dtype dwarf.Type, pos token.Pos, parent string) *Typ
                                tt.C = &TypeRepr{"struct %s", []interface{}{tag}}
                        }
                        tt.Go = g
-                       tt.NotInHeap = c.notInHeapStructs[tag]
+                       if c.incompleteStructs[tag] {
+                               tt.Go = c.Ident("_cgopackage.Incomplete")
+                       }
                        typedef[name.Name] = &tt
                }
 
@@ -2644,9 +2638,9 @@ func (c *typeConv) loadType(dtype dwarf.Type, pos token.Pos, parent string) *Typ
                        }
                }
                if c.badVoidPointerTypedef(dt) {
-                       // Treat this typedef as a pointer to a NotInHeap void.
+                       // Treat this typedef as a pointer to a _cgopackage.Incomplete.
                        s := *sub
-                       s.Go = c.goVoidPtrNoHeap
+                       s.Go = c.Ident("*_cgopackage.Incomplete")
                        sub = &s
                        // Make sure we update any previously computed type.
                        if oldType := typedef[name.Name]; oldType != nil {
@@ -2654,22 +2648,21 @@ func (c *typeConv) loadType(dtype dwarf.Type, pos token.Pos, parent string) *Typ
                        }
                }
                // Check for non-pointer "struct <tag>{...}; typedef struct <tag> *<name>"
-               // typedefs that should be marked NotInHeap.
+               // typedefs that should be marked Incomplete.
                if ptr, ok := dt.Type.(*dwarf.PtrType); ok {
                        if strct, ok := ptr.Type.(*dwarf.StructType); ok {
                                if c.badStructPointerTypedef(dt.Name, strct) {
-                                       c.notInHeapStructs[strct.StructName] = true
+                                       c.incompleteStructs[strct.StructName] = true
                                        // Make sure we update any previously computed type.
                                        name := "_Ctype_struct_" + strct.StructName
                                        if oldType := typedef[name]; oldType != nil {
-                                               oldType.NotInHeap = true
+                                               oldType.Go = c.Ident("_cgopackage.Incomplete")
                                        }
                                }
                        }
                }
                t.Go = name
                t.BadPointer = sub.BadPointer
-               t.NotInHeap = sub.NotInHeap
                if unionWithPointer[sub.Go] {
                        unionWithPointer[t.Go] = true
                }
@@ -2680,7 +2673,6 @@ func (c *typeConv) loadType(dtype dwarf.Type, pos token.Pos, parent string) *Typ
                        tt := *t
                        tt.Go = sub.Go
                        tt.BadPointer = sub.BadPointer
-                       tt.NotInHeap = sub.NotInHeap
                        typedef[name.Name] = &tt
                }
 
@@ -3204,7 +3196,7 @@ func (c *typeConv) anonymousStructTypedef(dt *dwarf.TypedefType) bool {
 // non-pointers in this type.
 // TODO: Currently our best solution is to find these manually and list them as
 // they come up. A better solution is desired.
-// Note: DEPRECATED. There is now a better solution. Search for NotInHeap in this file.
+// Note: DEPRECATED. There is now a better solution. Search for _cgopackage.Incomplete in this file.
 func (c *typeConv) badPointerTypedef(dt *dwarf.TypedefType) bool {
        if c.badCFType(dt) {
                return true
@@ -3218,7 +3210,7 @@ func (c *typeConv) badPointerTypedef(dt *dwarf.TypedefType) bool {
        return false
 }
 
-// badVoidPointerTypedef is like badPointerTypeDef, but for "void *" typedefs that should be NotInHeap.
+// badVoidPointerTypedef is like badPointerTypeDef, but for "void *" typedefs that should be _cgopackage.Incomplete.
 func (c *typeConv) badVoidPointerTypedef(dt *dwarf.TypedefType) bool {
        // Match the Windows HANDLE type (#42018).
        if goos != "windows" || dt.Name != "HANDLE" {
index e3434598b2eb09f44d60c88b08337598917d96bf..4f94d77c0ab74b703aa84082631cf6a57b22806c 100644 (file)
@@ -153,7 +153,6 @@ type Type struct {
        EnumValues map[string]int64
        Typedef    string
        BadPointer bool // this pointer type should be represented as a uintptr (deprecated)
-       NotInHeap  bool // this type should have a go:notinheap annotation
 }
 
 // A FuncType collects information about a function type in both the C and Go worlds.
index 119eca2be79e8cce2d3787573c5164d4fa7cc2b7..6a224598cc960cb849c7efbfb0d0ab030cccfabe 100644 (file)
@@ -81,11 +81,14 @@ func (p *Package) writeDefs() {
        fmt.Fprintf(fgo2, "// Code generated by cmd/cgo; DO NOT EDIT.\n\n")
        fmt.Fprintf(fgo2, "package %s\n\n", p.PackageName)
        fmt.Fprintf(fgo2, "import \"unsafe\"\n\n")
-       if !*gccgo && *importRuntimeCgo {
-               fmt.Fprintf(fgo2, "import _ \"runtime/cgo\"\n\n")
-       }
        if *importSyscall {
                fmt.Fprintf(fgo2, "import \"syscall\"\n\n")
+       }
+       if *importRuntimeCgo {
+               fmt.Fprintf(fgo2, "import _cgopackage \"runtime/cgo\"\n\n")
+               fmt.Fprintf(fgo2, "type _ _cgopackage.Incomplete\n") // prevent import-not-used error
+       }
+       if *importSyscall {
                fmt.Fprintf(fgo2, "var _ syscall.Errno\n")
        }
        fmt.Fprintf(fgo2, "func _Cgo_ptr(ptr unsafe.Pointer) unsafe.Pointer { return ptr }\n\n")
@@ -109,9 +112,6 @@ func (p *Package) writeDefs() {
        sort.Strings(typedefNames)
        for _, name := range typedefNames {
                def := typedef[name]
-               if def.NotInHeap {
-                       fmt.Fprintf(fgo2, "//go:notinheap\n")
-               }
                fmt.Fprintf(fgo2, "type %s ", name)
                // We don't have source info for these types, so write them out without source info.
                // Otherwise types would look like:
@@ -136,7 +136,6 @@ func (p *Package) writeDefs() {
                fmt.Fprintf(fgo2, "%s", buf.Bytes())
                fmt.Fprintf(fgo2, "\n\n")
        }
-       fmt.Fprintf(fgo2, "//go:notinheap\ntype _Ctype_void_notinheap struct{}\n\n")
        if *gccgo {
                fmt.Fprintf(fgo2, "type _Ctype_void byte\n")
        } else {
index 4b7046e2cc62db0e47d818ff085fa1a84488dca2..b8473e532d4f7e75345a42cc30b01e5f380c569c 100644 (file)
@@ -31,3 +31,10 @@ package cgo
 
 */
 import "C"
+
+import "runtime/internal/sys"
+
+// Incomplete is used specifically for the semantics of incomplete C types.
+type Incomplete struct {
+       _ sys.NotInHeap
+}