Skip to content

Commit 255f356

Browse files
aykevldeadprogram
authored andcommitted
compiler: add support for new language features of Go 1.17
1 parent 8e88e56 commit 255f356

File tree

11 files changed

+361
-12
lines changed

11 files changed

+361
-12
lines changed

compiler/asserts.go

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,55 @@ func (b *builder) createSliceBoundsCheck(capacity, low, high, max llvm.Value, lo
101101
b.createRuntimeAssert(outOfBounds, "slice", "slicePanic")
102102
}
103103

104+
// createSliceToArrayPointerCheck adds a check for slice-to-array pointer
105+
// conversions. This conversion was added in Go 1.17. For details, see:
106+
// https://tip.golang.org/ref/spec#Conversions_from_slice_to_array_pointer
107+
func (b *builder) createSliceToArrayPointerCheck(sliceLen llvm.Value, arrayLen int64) {
108+
// From the spec:
109+
// > If the length of the slice is less than the length of the array, a
110+
// > run-time panic occurs.
111+
arrayLenValue := llvm.ConstInt(b.uintptrType, uint64(arrayLen), false)
112+
isLess := b.CreateICmp(llvm.IntULT, sliceLen, arrayLenValue, "")
113+
b.createRuntimeAssert(isLess, "slicetoarray", "sliceToArrayPointerPanic")
114+
}
115+
116+
// createUnsafeSliceCheck inserts a runtime check used for unsafe.Slice. This
117+
// function must panic if the ptr/len parameters are invalid.
118+
func (b *builder) createUnsafeSliceCheck(ptr, len llvm.Value, lenType *types.Basic) {
119+
// From the documentation of unsafe.Slice:
120+
// > At run time, if len is negative, or if ptr is nil and len is not
121+
// > zero, a run-time panic occurs.
122+
// However, in practice, it is also necessary to check that the length is
123+
// not too big that a GEP wouldn't be possible without wrapping the pointer.
124+
// These two checks (non-negative and not too big) can be merged into one
125+
// using an unsiged greater than.
126+
127+
// Make sure the len value is at least as big as a uintptr.
128+
if len.Type().IntTypeWidth() < b.uintptrType.IntTypeWidth() {
129+
if lenType.Info()&types.IsUnsigned != 0 {
130+
len = b.CreateZExt(len, b.uintptrType, "")
131+
} else {
132+
len = b.CreateSExt(len, b.uintptrType, "")
133+
}
134+
}
135+
136+
// Determine the maximum slice size, and therefore the maximum value of the
137+
// len parameter.
138+
maxSize := b.maxSliceSize(ptr.Type().ElementType())
139+
maxSizeValue := llvm.ConstInt(len.Type(), maxSize, false)
140+
141+
// Do the check. By using unsigned greater than for the length check, signed
142+
// negative values are also checked (which are very large numbers when
143+
// interpreted as signed values).
144+
zero := llvm.ConstInt(len.Type(), 0, false)
145+
lenOutOfBounds := b.CreateICmp(llvm.IntUGT, len, maxSizeValue, "")
146+
ptrIsNil := b.CreateICmp(llvm.IntEQ, ptr, llvm.ConstNull(ptr.Type()), "")
147+
lenIsNotZero := b.CreateICmp(llvm.IntNE, len, zero, "")
148+
assert := b.CreateAnd(ptrIsNil, lenIsNotZero, "")
149+
assert = b.CreateOr(assert, lenOutOfBounds, "")
150+
b.createRuntimeAssert(assert, "unsafe.Slice", "unsafeSlicePanic")
151+
}
152+
104153
// createChanBoundsCheck creates a bounds check before creating a new channel to
105154
// check that the value is not too big for runtime.chanMake.
106155
func (b *builder) createChanBoundsCheck(elementSize uint64, bufSize llvm.Value, bufSizeType *types.Basic, pos token.Pos) {

compiler/compiler.go

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1293,6 +1293,38 @@ func (b *builder) createBuiltin(argTypes []types.Type, argValues []llvm.Value, c
12931293
case "ssa:wrapnilchk":
12941294
// TODO: do an actual nil check?
12951295
return argValues[0], nil
1296+
1297+
// Builtins from the unsafe package.
1298+
case "Add": // unsafe.Add
1299+
// This is basically just a GEP operation.
1300+
// Note: the pointer is always of type *i8.
1301+
ptr := argValues[0]
1302+
len := argValues[1]
1303+
return b.CreateGEP(ptr, []llvm.Value{len}, ""), nil
1304+
case "Slice": // unsafe.Slice
1305+
// This creates a slice from a pointer and a length.
1306+
// Note that the exception mentioned in the documentation (if the
1307+
// pointer and length are nil, the slice is also nil) is trivially
1308+
// already the case.
1309+
ptr := argValues[0]
1310+
len := argValues[1]
1311+
slice := llvm.Undef(b.ctx.StructType([]llvm.Type{
1312+
ptr.Type(),
1313+
b.uintptrType,
1314+
b.uintptrType,
1315+
}, false))
1316+
b.createUnsafeSliceCheck(ptr, len, argTypes[1].Underlying().(*types.Basic))
1317+
if len.Type().IntTypeWidth() < b.uintptrType.IntTypeWidth() {
1318+
// Too small, zero-extend len.
1319+
len = b.CreateZExt(len, b.uintptrType, "")
1320+
} else if len.Type().IntTypeWidth() > b.uintptrType.IntTypeWidth() {
1321+
// Too big, truncate len.
1322+
len = b.CreateTrunc(len, b.uintptrType, "")
1323+
}
1324+
slice = b.CreateInsertValue(slice, ptr, 0, "")
1325+
slice = b.CreateInsertValue(slice, len, 1, "")
1326+
slice = b.CreateInsertValue(slice, len, 2, "")
1327+
return slice, nil
12961328
default:
12971329
return llvm.Value{}, b.makeError(pos, "todo: builtin: "+callName)
12981330
}
@@ -1928,6 +1960,17 @@ func (b *builder) createExpr(expr ssa.Value) (llvm.Value, error) {
19281960
default:
19291961
return llvm.Value{}, b.makeError(expr.Pos(), "unknown slice type: "+typ.String())
19301962
}
1963+
case *ssa.SliceToArrayPointer:
1964+
// Conversion from a slice to an array pointer, as the name clearly
1965+
// says. This requires a runtime check to make sure the slice is at
1966+
// least as big as the array.
1967+
slice := b.getValue(expr.X)
1968+
sliceLen := b.CreateExtractValue(slice, 1, "")
1969+
arrayLen := expr.Type().Underlying().(*types.Pointer).Elem().Underlying().(*types.Array).Len()
1970+
b.createSliceToArrayPointerCheck(sliceLen, arrayLen)
1971+
ptr := b.CreateExtractValue(slice, 0, "")
1972+
ptr = b.CreateBitCast(ptr, b.getLLVMType(expr.Type()), "")
1973+
return ptr, nil
19311974
case *ssa.TypeAssert:
19321975
return b.createTypeAssert(expr), nil
19331976
case *ssa.UnOp:

compiler/compiler_test.go

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,19 @@ import (
99
"testing"
1010

1111
"github.com/tinygo-org/tinygo/compileopts"
12+
"github.com/tinygo-org/tinygo/goenv"
1213
"github.com/tinygo-org/tinygo/loader"
1314
"tinygo.org/x/go-llvm"
1415
)
1516

1617
// Pass -update to go test to update the output of the test files.
1718
var flagUpdate = flag.Bool("update", false, "update tests based on test output")
1819

20+
type testCase struct {
21+
file string
22+
target string
23+
}
24+
1925
// Basic tests for the compiler. Build some Go files and compare the output with
2026
// the expected LLVM IR for regression testing.
2127
func TestCompiler(t *testing.T) {
@@ -34,10 +40,7 @@ func TestCompiler(t *testing.T) {
3440
t.Skip("compiler tests require LLVM 11 or above, got LLVM ", llvm.Version)
3541
}
3642

37-
tests := []struct {
38-
file string
39-
target string
40-
}{
43+
tests := []testCase{
4144
{"basic.go", ""},
4245
{"pointer.go", ""},
4346
{"slice.go", ""},
@@ -52,6 +55,14 @@ func TestCompiler(t *testing.T) {
5255
{"intrinsics.go", "wasm"},
5356
}
5457

58+
_, minor, err := goenv.GetGorootVersion(goenv.Get("GOROOT"))
59+
if err != nil {
60+
t.Fatal("could not read Go version:", err)
61+
}
62+
if minor >= 17 {
63+
tests = append(tests, testCase{"go1.17.go", ""})
64+
}
65+
5566
for _, tc := range tests {
5667
name := tc.file
5768
targetString := "wasm"

compiler/testdata/go1.17.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package main
2+
3+
// Test changes to the language introduced in Go 1.17.
4+
// For details, see: https://tip.golang.org/doc/go1.17#language
5+
// These tests should be merged into the regular slice tests once Go 1.17 is the
6+
// minimun Go version for TinyGo.
7+
8+
import "unsafe"
9+
10+
func Add32(p unsafe.Pointer, len int) unsafe.Pointer {
11+
return unsafe.Add(p, len)
12+
}
13+
14+
func Add64(p unsafe.Pointer, len int64) unsafe.Pointer {
15+
return unsafe.Add(p, len)
16+
}
17+
18+
func SliceToArray(s []int) *[4]int {
19+
return (*[4]int)(s)
20+
}
21+
22+
func SliceToArrayConst() *[4]int {
23+
s := make([]int, 6)
24+
return (*[4]int)(s)
25+
}
26+
27+
func SliceInt(ptr *int, len int) []int {
28+
return unsafe.Slice(ptr, len)
29+
}
30+
31+
func SliceUint16(ptr *byte, len uint16) []byte {
32+
return unsafe.Slice(ptr, len)
33+
}
34+
35+
func SliceUint64(ptr *int, len uint64) []int {
36+
return unsafe.Slice(ptr, len)
37+
}
38+
39+
func SliceInt64(ptr *int, len int64) []int {
40+
return unsafe.Slice(ptr, len)
41+
}

compiler/testdata/go1.17.ll

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
; ModuleID = 'go1.17.go'
2+
source_filename = "go1.17.go"
3+
target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
4+
target triple = "wasm32--wasi"
5+
6+
declare noalias nonnull i8* @runtime.alloc(i32, i8*, i8*)
7+
8+
define hidden void @main.init(i8* %context, i8* %parentHandle) unnamed_addr {
9+
entry:
10+
ret void
11+
}
12+
13+
define hidden i8* @main.Add32(i8* %p, i32 %len, i8* %context, i8* %parentHandle) unnamed_addr {
14+
entry:
15+
%0 = getelementptr i8, i8* %p, i32 %len
16+
ret i8* %0
17+
}
18+
19+
define hidden i8* @main.Add64(i8* %p, i64 %len, i8* %context, i8* %parentHandle) unnamed_addr {
20+
entry:
21+
%0 = trunc i64 %len to i32
22+
%1 = getelementptr i8, i8* %p, i32 %0
23+
ret i8* %1
24+
}
25+
26+
define hidden [4 x i32]* @main.SliceToArray(i32* %s.data, i32 %s.len, i32 %s.cap, i8* %context, i8* %parentHandle) unnamed_addr {
27+
entry:
28+
%0 = icmp ult i32 %s.len, 4
29+
br i1 %0, label %slicetoarray.throw, label %slicetoarray.next
30+
31+
slicetoarray.throw: ; preds = %entry
32+
call void @runtime.sliceToArrayPointerPanic(i8* undef, i8* null)
33+
unreachable
34+
35+
slicetoarray.next: ; preds = %entry
36+
%1 = bitcast i32* %s.data to [4 x i32]*
37+
ret [4 x i32]* %1
38+
}
39+
40+
declare void @runtime.sliceToArrayPointerPanic(i8*, i8*)
41+
42+
define hidden [4 x i32]* @main.SliceToArrayConst(i8* %context, i8* %parentHandle) unnamed_addr {
43+
entry:
44+
%makeslice = call i8* @runtime.alloc(i32 24, i8* undef, i8* null)
45+
br i1 false, label %slicetoarray.throw, label %slicetoarray.next
46+
47+
slicetoarray.throw: ; preds = %entry
48+
unreachable
49+
50+
slicetoarray.next: ; preds = %entry
51+
%0 = bitcast i8* %makeslice to [4 x i32]*
52+
ret [4 x i32]* %0
53+
}
54+
55+
define hidden { i32*, i32, i32 } @main.SliceInt(i32* dereferenceable_or_null(4) %ptr, i32 %len, i8* %context, i8* %parentHandle) unnamed_addr {
56+
entry:
57+
%0 = icmp ugt i32 %len, 1073741823
58+
%1 = icmp eq i32* %ptr, null
59+
%2 = icmp ne i32 %len, 0
60+
%3 = and i1 %1, %2
61+
%4 = or i1 %3, %0
62+
br i1 %4, label %unsafe.Slice.throw, label %unsafe.Slice.next
63+
64+
unsafe.Slice.throw: ; preds = %entry
65+
call void @runtime.unsafeSlicePanic(i8* undef, i8* null)
66+
unreachable
67+
68+
unsafe.Slice.next: ; preds = %entry
69+
%5 = insertvalue { i32*, i32, i32 } undef, i32* %ptr, 0
70+
%6 = insertvalue { i32*, i32, i32 } %5, i32 %len, 1
71+
%7 = insertvalue { i32*, i32, i32 } %6, i32 %len, 2
72+
ret { i32*, i32, i32 } %7
73+
}
74+
75+
declare void @runtime.unsafeSlicePanic(i8*, i8*)
76+
77+
define hidden { i8*, i32, i32 } @main.SliceUint16(i8* dereferenceable_or_null(1) %ptr, i16 %len, i8* %context, i8* %parentHandle) unnamed_addr {
78+
entry:
79+
%0 = icmp eq i8* %ptr, null
80+
%1 = icmp ne i16 %len, 0
81+
%2 = and i1 %0, %1
82+
br i1 %2, label %unsafe.Slice.throw, label %unsafe.Slice.next
83+
84+
unsafe.Slice.throw: ; preds = %entry
85+
call void @runtime.unsafeSlicePanic(i8* undef, i8* null)
86+
unreachable
87+
88+
unsafe.Slice.next: ; preds = %entry
89+
%3 = zext i16 %len to i32
90+
%4 = insertvalue { i8*, i32, i32 } undef, i8* %ptr, 0
91+
%5 = insertvalue { i8*, i32, i32 } %4, i32 %3, 1
92+
%6 = insertvalue { i8*, i32, i32 } %5, i32 %3, 2
93+
ret { i8*, i32, i32 } %6
94+
}
95+
96+
define hidden { i32*, i32, i32 } @main.SliceUint64(i32* dereferenceable_or_null(4) %ptr, i64 %len, i8* %context, i8* %parentHandle) unnamed_addr {
97+
entry:
98+
%0 = icmp ugt i64 %len, 1073741823
99+
%1 = icmp eq i32* %ptr, null
100+
%2 = icmp ne i64 %len, 0
101+
%3 = and i1 %1, %2
102+
%4 = or i1 %3, %0
103+
br i1 %4, label %unsafe.Slice.throw, label %unsafe.Slice.next
104+
105+
unsafe.Slice.throw: ; preds = %entry
106+
call void @runtime.unsafeSlicePanic(i8* undef, i8* null)
107+
unreachable
108+
109+
unsafe.Slice.next: ; preds = %entry
110+
%5 = trunc i64 %len to i32
111+
%6 = insertvalue { i32*, i32, i32 } undef, i32* %ptr, 0
112+
%7 = insertvalue { i32*, i32, i32 } %6, i32 %5, 1
113+
%8 = insertvalue { i32*, i32, i32 } %7, i32 %5, 2
114+
ret { i32*, i32, i32 } %8
115+
}
116+
117+
define hidden { i32*, i32, i32 } @main.SliceInt64(i32* dereferenceable_or_null(4) %ptr, i64 %len, i8* %context, i8* %parentHandle) unnamed_addr {
118+
entry:
119+
%0 = icmp ugt i64 %len, 1073741823
120+
%1 = icmp eq i32* %ptr, null
121+
%2 = icmp ne i64 %len, 0
122+
%3 = and i1 %1, %2
123+
%4 = or i1 %3, %0
124+
br i1 %4, label %unsafe.Slice.throw, label %unsafe.Slice.next
125+
126+
unsafe.Slice.throw: ; preds = %entry
127+
call void @runtime.unsafeSlicePanic(i8* undef, i8* null)
128+
unreachable
129+
130+
unsafe.Slice.next: ; preds = %entry
131+
%5 = trunc i64 %len to i32
132+
%6 = insertvalue { i32*, i32, i32 } undef, i32* %ptr, 0
133+
%7 = insertvalue { i32*, i32, i32 } %6, i32 %5, 1
134+
%8 = insertvalue { i32*, i32, i32 } %7, i32 %5, 2
135+
ret { i32*, i32, i32 } %8
136+
}

go.mod

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ require (
1010
github.com/marcinbor85/gohex v0.0.0-20200531091804-343a4b548892
1111
github.com/mattn/go-colorable v0.1.8
1212
go.bug.st/serial v1.1.2
13-
golang.org/x/sys v0.0.0-20210113181707-4bcb84eeeb78
14-
golang.org/x/tools v0.0.0-20200216192241-b320d3a0f5a2
13+
golang.org/x/sys v0.0.0-20210510120138-977fb7262007
14+
golang.org/x/tools v0.1.6-0.20210813165731-45389f592fe9
1515
tinygo.org/x/go-llvm v0.0.0-20210325115028-e7b85195e81c
1616
)

go.sum

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Ky
3030
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
3131
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
3232
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
33+
github.com/yuin/goldmark v1.3.5 h1:dPmz1Snjq0kmkz159iL7S6WzdahUTHnHB5M56WFVifs=
34+
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
3335
go.bug.st/serial v1.0.0 h1:ogEPzrllCsnG00EqKRjeYvPRsO7NJW6DqykzkdD6E/k=
3436
go.bug.st/serial v1.0.0/go.mod h1:rpXPISGjuNjPTRTcMlxi9lN6LoIPxd1ixVjBd8aSk/Q=
3537
go.bug.st/serial v1.1.2 h1:6xDpbta8KJ+VLRTeM8ghhxXRMLE/Lr8h9iDKwydarAY=
@@ -38,23 +40,32 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk
3840
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
3941
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee h1:WG0RUwxtNT4qqaXX3DPA8zHFNm/D9xaBpxzHt1WcA/E=
4042
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
43+
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
4144
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
4245
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
46+
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
4347
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
48+
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
4449
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
4550
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
46-
golang.org/x/sys v0.0.0-20191128015809-6d18c012aee9 h1:ZBzSG/7F4eNKz2L3GE9o300RX0Az1Bw5HF7PDraD+qU=
47-
golang.org/x/sys v0.0.0-20191128015809-6d18c012aee9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
4851
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
4952
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
5053
golang.org/x/sys v0.0.0-20200909081042-eff7692f9009/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
51-
golang.org/x/sys v0.0.0-20210113181707-4bcb84eeeb78 h1:nVuTkr9L6Bq62qpUqKo/RnZCFfzDBL0bYo6w9OJUqZY=
54+
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
5255
golang.org/x/sys v0.0.0-20210113181707-4bcb84eeeb78/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
56+
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
57+
golang.org/x/sys v0.0.0-20210510120138-977fb7262007 h1:gG67DSER+11cZvqIMb8S8bt0vZtiN6xWYARwirrOSfE=
58+
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
59+
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
5360
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
54-
golang.org/x/tools v0.0.0-20200216192241-b320d3a0f5a2 h1:0sfSpGSa544Fwnbot3Oxq/U6SXqjty6Jy/3wRhVS7ig=
55-
golang.org/x/tools v0.0.0-20200216192241-b320d3a0f5a2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
56-
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898 h1:/atklqdjdhuosWIl6AIbOeHJjicWYPqR9bpxqxYG2pA=
61+
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
62+
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
63+
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
64+
golang.org/x/tools v0.1.6-0.20210813165731-45389f592fe9 h1:nvvuMxmx1q0gfRki3T0hjG8EwAcVCs91oWAXvyt4zhI=
65+
golang.org/x/tools v0.1.6-0.20210813165731-45389f592fe9/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
66+
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
5767
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
68+
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
5869
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
5970
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
6071
tinygo.org/x/go-llvm v0.0.0-20210308112806-9ef958b6bed4 h1:CMUHxVTb+UuUePuMf8vkWjZ3gTp9BBK91KrgOCwoNHs=

0 commit comments

Comments
 (0)