]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: disallow converting string to notinheap slice
authorMatthew Dempsky <mdempsky@google.com>
Tue, 16 Oct 2018 22:31:07 +0000 (15:31 -0700)
committerMatthew Dempsky <mdempsky@google.com>
Fri, 2 Nov 2018 19:53:59 +0000 (19:53 +0000)
Unlikely to happen in practice, but easy enough to prevent and might
as well do so for completeness.

Fixes #28243.

Change-Id: I848c3af49cb923f088e9490c6a79373e182fad08
Reviewed-on: https://go-review.googlesource.com/c/142719
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: Austin Clements <austin@google.com>
src/cmd/compile/internal/gc/subr.go
test/notinheap.go

index df3bde86eace5d835ac1f845aea8ad86166f0225..97f7e4880d9c7cc6c8c5645274ba6993b8dc5947 100644 (file)
@@ -696,14 +696,22 @@ func convertop(src *types.Type, dst *types.Type, why *string) Op {
        }
 
        // Conversions from regular to go:notinheap are not allowed
-       // (unless it's unsafe.Pointer). This is a runtime-specific
-       // rule.
+       // (unless it's unsafe.Pointer). These are runtime-specific
+       // rules.
+       // (a) Disallow (*T) to (*U) where T is go:notinheap but U isn't.
        if src.IsPtr() && dst.IsPtr() && dst.Elem().NotInHeap() && !src.Elem().NotInHeap() {
                if why != nil {
                        *why = fmt.Sprintf(":\n\t%v is go:notinheap, but %v is not", dst.Elem(), src.Elem())
                }
                return 0
        }
+       // (b) Disallow string to []T where T is go:notinheap.
+       if src.IsString() && dst.IsSlice() && dst.Elem().NotInHeap() && (dst.Elem().Etype == types.Bytetype.Etype || dst.Elem().Etype == types.Runetype.Etype) {
+               if why != nil {
+                       *why = fmt.Sprintf(":\n\t%v is go:notinheap", dst.Elem())
+               }
+               return 0
+       }
 
        // 1. src can be assigned to dst.
        op := assignop(src, dst, why)
index 44b79646ef70ca62093fbffbc3072374e971e488..16c3f8faf0a6735fef025e5a142cbb32ff340fda 100644 (file)
@@ -46,10 +46,18 @@ type t1 struct{ x int }
 //go:notinheap
 type t2 t1
 
+//go:notinheap
+type t3 byte
+
+//go:notinheap
+type t4 rune
+
 var sink interface{}
 
 func i() {
        sink = new(t1)                     // no error
        sink = (*t2)(new(t1))              // ERROR "cannot convert(.|\n)*t2 is go:notinheap"
        sink = (*t2)(new(struct{ x int })) // ERROR "cannot convert(.|\n)*t2 is go:notinheap"
+       sink = []t3("foo")                 // ERROR "cannot convert(.|\n)*t3 is go:notinheap"
+       sink = []t4("bar")                 // ERROR "cannot convert(.|\n)*t4 is go:notinheap"
 }