mirror of
https://github.com/golang/go
synced 2024-11-23 04:20:03 -07:00
cmd/compile: remove go:notinheap pragma
Updates #46731 Change-Id: I247fa9c7ca97feb9053665da7ff56e7f5b571f74 Reviewed-on: https://go-review.googlesource.com/c/go/+/422815 Reviewed-by: Keith Randall <khr@golang.org> Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com> Reviewed-by: David Chase <drchase@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Joedian Reid <joedian@golang.org>
This commit is contained in:
parent
0ee0bb1003
commit
8bbb362f4c
@ -454,9 +454,6 @@ const (
|
||||
Nowritebarrierrec // error on write barrier in this or recursive callees
|
||||
Yeswritebarrierrec // cancels Nowritebarrierrec in this function and callees
|
||||
|
||||
// Runtime and cgo type pragmas
|
||||
NotInHeap // values of this type must not be heap allocated
|
||||
|
||||
// Go command pragmas
|
||||
GoBuildPragma
|
||||
|
||||
|
@ -212,33 +212,9 @@ func (g *irgen) typeDecl(out *ir.Nodes, decl *syntax.TypeDecl) {
|
||||
ntyp.SetVargen()
|
||||
}
|
||||
|
||||
pragmas := g.pragmaFlags(decl.Pragma, typePragmas)
|
||||
pragmas := g.pragmaFlags(decl.Pragma, 0)
|
||||
name.SetPragma(pragmas) // TODO(mdempsky): Is this still needed?
|
||||
|
||||
if pragmas&ir.NotInHeap != 0 {
|
||||
ntyp.SetNotInHeap(true)
|
||||
}
|
||||
|
||||
// We need to use g.typeExpr(decl.Type) here to ensure that for
|
||||
// chained, defined-type declarations like:
|
||||
//
|
||||
// type T U
|
||||
//
|
||||
// //go:notinheap
|
||||
// type U struct { … }
|
||||
//
|
||||
// we mark both T and U as NotInHeap. If we instead used just
|
||||
// g.typ(otyp.Underlying()), then we'd instead set T's underlying
|
||||
// type directly to the struct type (which is not marked NotInHeap)
|
||||
// and fail to mark T as NotInHeap.
|
||||
//
|
||||
// Also, we rely here on Type.SetUnderlying allowing passing a
|
||||
// defined type and handling forward references like from T to U
|
||||
// above. Contrast with go/types's Named.SetUnderlying, which
|
||||
// disallows this.
|
||||
//
|
||||
// [mdempsky: Subtleties like these are why I always vehemently
|
||||
// object to new type pragmas.]
|
||||
ntyp.SetUnderlying(g.typeExpr(decl.Type))
|
||||
|
||||
tparams := otyp.(*types2.Named).TypeParams()
|
||||
|
@ -36,8 +36,6 @@ const (
|
||||
ir.Nowritebarrier |
|
||||
ir.Nowritebarrierrec |
|
||||
ir.Yeswritebarrierrec
|
||||
|
||||
typePragmas = ir.NotInHeap
|
||||
)
|
||||
|
||||
func pragmaFlag(verb string) ir.PragmaFlag {
|
||||
@ -77,8 +75,6 @@ func pragmaFlag(verb string) ir.PragmaFlag {
|
||||
return ir.UintptrEscapes | ir.UintptrKeepAlive // implies UintptrKeepAlive
|
||||
case "go:registerparams": // TODO(register args) remove after register abi is working
|
||||
return ir.RegisterParams
|
||||
case "go:notinheap":
|
||||
return ir.NotInHeap
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
@ -344,9 +344,6 @@ func (p *noder) pragma(pos syntax.Pos, blankLine bool, text string, old syntax.P
|
||||
if flag == 0 && !allowedStdPragmas[verb] && base.Flag.Std {
|
||||
p.error(syntax.Error{Pos: pos, Msg: fmt.Sprintf("//%s is not allowed in the standard library", verb)})
|
||||
}
|
||||
if flag == ir.NotInHeap && *base.Flag.LowerP != "runtime/internal/sys" {
|
||||
p.error(syntax.Error{Pos: pos, Msg: "//go:notinheap only allowed in runtime/internal/sys"})
|
||||
}
|
||||
pragma.Flag |= flag
|
||||
pragma.Pos = append(pragma.Pos, pragmaPos{flag, pos})
|
||||
}
|
||||
|
@ -1096,9 +1096,6 @@ func (r *reader) typeExt(name *ir.Name) {
|
||||
}
|
||||
|
||||
name.SetPragma(r.pragmaFlag())
|
||||
if name.Pragma()&ir.NotInHeap != 0 {
|
||||
typ.SetNotInHeap(true)
|
||||
}
|
||||
|
||||
typecheck.SetBaseTypeIndex(typ, r.Int64(), r.Int64())
|
||||
}
|
||||
@ -2440,16 +2437,6 @@ func (r *reader) expr() (res ir.Node) {
|
||||
// TODO(mdempsky): Stop constructing expressions of untyped type.
|
||||
x = typecheck.DefaultLit(x, typ)
|
||||
|
||||
if op, why := typecheck.Convertop(x.Op() == ir.OLITERAL, x.Type(), typ); op == ir.OXXX {
|
||||
// types2 ensured that x is convertable to typ under standard Go
|
||||
// semantics, but cmd/compile also disallows some conversions
|
||||
// involving //go:notinheap.
|
||||
//
|
||||
// TODO(mdempsky): This can be removed after #46731 is implemented.
|
||||
base.ErrorfAt(pos, "cannot convert %L to type %v%v", x, typ, why)
|
||||
base.ErrorExit() // harsh, but prevents constructing invalid IR
|
||||
}
|
||||
|
||||
ce := ir.NewConvExpr(pos, ir.OCONV, typ, x)
|
||||
ce.TypeWord, ce.SrcRType = typeWord, srcRType
|
||||
if implicit {
|
||||
|
@ -2355,7 +2355,7 @@ func (c *declCollector) Visit(n syntax.Node) syntax.Visitor {
|
||||
if n.Alias {
|
||||
pw.checkPragmas(n.Pragma, 0, false)
|
||||
} else {
|
||||
pw.checkPragmas(n.Pragma, typePragmas, false)
|
||||
pw.checkPragmas(n.Pragma, 0, false)
|
||||
|
||||
// Assign a unique ID to function-scoped defined types.
|
||||
if c.withinFunc {
|
||||
|
@ -18,7 +18,7 @@ func Set(t *types.Type, off int64, bv bitvec.BitVec) {
|
||||
base.Fatalf("typebits.Set: invalid initial alignment: type %v has alignment %d, but offset is %v", t, uint8(t.Alignment()), off)
|
||||
}
|
||||
if !t.HasPointers() {
|
||||
// Note: this case ensures that pointers to go:notinheap types
|
||||
// Note: this case ensures that pointers to not-in-heap types
|
||||
// are not considered pointers by garbage collection and stack copying.
|
||||
return
|
||||
}
|
||||
|
@ -901,7 +901,7 @@ func tcUnsafeSlice(n *ir.BinaryExpr) *ir.BinaryExpr {
|
||||
base.Errorf("first argument to unsafe.Slice must be pointer; have %L", t)
|
||||
} else if t.Elem().NotInHeap() {
|
||||
// TODO(mdempsky): This can be relaxed, but should only affect the
|
||||
// Go runtime itself. End users should only see //go:notinheap
|
||||
// Go runtime itself. End users should only see not-in-heap
|
||||
// types due to incomplete C structs in cgo, and those types don't
|
||||
// have a meaningful size anyway.
|
||||
base.Errorf("unsafe.Slice of incomplete (or unallocatable) type not allowed")
|
||||
|
@ -471,15 +471,15 @@ func Convertop(srcConstant bool, src, dst *types.Type) (ir.Op, string) {
|
||||
return ir.OXXX, ""
|
||||
}
|
||||
|
||||
// Conversions from regular to go:notinheap are not allowed
|
||||
// Conversions from regular to not-in-heap are not allowed
|
||||
// (unless it's unsafe.Pointer). These are runtime-specific
|
||||
// rules.
|
||||
// (a) Disallow (*T) to (*U) where T is go:notinheap but U isn't.
|
||||
// (a) Disallow (*T) to (*U) where T is not-in-heap but U isn't.
|
||||
if src.IsPtr() && dst.IsPtr() && dst.Elem().NotInHeap() && !src.Elem().NotInHeap() {
|
||||
why := fmt.Sprintf(":\n\t%v is incomplete (or unallocatable), but %v is not", dst.Elem(), src.Elem())
|
||||
return ir.OXXX, why
|
||||
}
|
||||
// (b) Disallow string to []T where T is go:notinheap.
|
||||
// (b) Disallow string to []T where T is not-in-heap.
|
||||
if src.IsString() && dst.IsSlice() && dst.Elem().NotInHeap() && (dst.Elem().Kind() == types.ByteType.Kind() || dst.Elem().Kind() == types.RuneType.Kind()) {
|
||||
why := fmt.Sprintf(":\n\t%v is incomplete (or unallocatable)", dst.Elem())
|
||||
return ir.OXXX, why
|
||||
|
Loading…
Reference in New Issue
Block a user