diff --git a/.circleci/config.yml b/.circleci/config.yml index 31d6051f5e..d49cdc9337 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -229,14 +229,14 @@ commands: - run: name: "Install dependencies" command: | - curl https://dl.google.com/go/go1.13.darwin-amd64.tar.gz -o go1.13.darwin-amd64.tar.gz - sudo tar -C /usr/local -xzf go1.13.darwin-amd64.tar.gz + curl https://dl.google.com/go/go1.14.darwin-amd64.tar.gz -o go1.14.darwin-amd64.tar.gz + sudo tar -C /usr/local -xzf go1.14.darwin-amd64.tar.gz ln -s /usr/local/go/bin/go /usr/local/bin/go HOMEBREW_NO_AUTO_UPDATE=1 brew install qemu - restore_cache: keys: - - go-cache-macos-v2-{{ checksum "go.mod" }}-{{ .Environment.CIRCLE_PREVIOUS_BUILD_NUM }} - - go-cache-macos-v2-{{ checksum "go.mod" }} + - go-cache-macos-v3-{{ checksum "go.mod" }}-{{ .Environment.CIRCLE_PREVIOUS_BUILD_NUM }} + - go-cache-macos-v3-{{ checksum "go.mod" }} - restore_cache: keys: - llvm-source-9-macos-v0 @@ -298,7 +298,7 @@ commands: sudo tar -C /usr/local --strip-components=1 -xf riscv64-unknown-elf-gcc-8.2.0-2019.05.3-x86_64-apple-darwin.tar.gz - run: make smoketest AVR=0 - save_cache: - key: go-cache-macos-v2-{{ checksum "go.mod" }}-{{ .Environment.CIRCLE_BUILD_NUM }} + key: go-cache-macos-v3-{{ checksum "go.mod" }}-{{ .Environment.CIRCLE_BUILD_NUM }} paths: - ~/.cache/go-build - ~/.cache/tinygo @@ -321,6 +321,11 @@ jobs: - image: circleci/golang:1.13-buster steps: - test-linux + test-llvm9-go114: + docker: + - image: circleci/golang:1.14-buster + steps: + - test-linux assert-test-linux: docker: - image: circleci/golang:1.13-stretch @@ -346,6 +351,7 @@ workflows: - test-llvm9-go111 - test-llvm9-go112 - test-llvm9-go113 + - test-llvm9-go114 - build-linux - build-macos - assert-test-linux diff --git a/azure-pipelines.yml b/azure-pipelines.yml index d8c4b8a473..b8942a8c7c 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -12,7 +12,7 @@ jobs: steps: - task: GoTool@0 inputs: - version: '1.13.8' + version: '1.14.1' - checkout: self - task: CacheBeta@0 displayName: Cache LLVM source diff --git a/builder/config.go b/builder/config.go index 8bb3a1162f..aabf82ac5a 100644 --- a/builder/config.go +++ b/builder/config.go @@ -25,8 +25,8 @@ func NewConfig(options *compileopts.Options) (*compileopts.Config, error) { if err != nil { return nil, fmt.Errorf("could not read version from GOROOT (%v): %v", goroot, err) } - if major != 1 || (minor != 11 && minor != 12 && minor != 13) { - return nil, fmt.Errorf("requires go version 1.11, 1.12, or 1.13, got go%d.%d", major, minor) + if major != 1 || minor < 11 || minor > 14 { + return nil, fmt.Errorf("requires go version 1.11, 1.12, 1.13, or 1.14, got go%d.%d", major, minor) } clangHeaderPath := getClangHeaderPath(goenv.Get("TINYGOROOT")) return &compileopts.Config{ diff --git a/cgo/cgo_test.go b/cgo/cgo_test.go index e9ae2f43e7..86f1329b8a 100644 --- a/cgo/cgo_test.go +++ b/cgo/cgo_test.go @@ -11,6 +11,7 @@ import ( "go/types" "io/ioutil" "path/filepath" + "regexp" "runtime" "strings" "testing" @@ -19,6 +20,22 @@ import ( // Pass -update to go test to update the output of the test files. var flagUpdate = flag.Bool("update", false, "Update images based on test output.") +// normalizeResult normalizes test results across Go versions. +// Currently, it does so by using consistent newlines, and wrapping +// function contents to be consistent with Go 1.14. +func normalizeResult(result string) string { + actual := strings.Replace(result, "\r\n", "\n", -1) + + // Make sure all functions are wrapped, even those that would otherwise be + // single-line functions. This is necessary because Go 1.14 changed the way + // such functions are wrapped and it's important to have consistent test + // results. + re := regexp.MustCompile(`func \((.+)\)( .*?) +{ (.+) }`) + actual = re.ReplaceAllString(actual, "func ($1)$2 {\n\t$3\n}") + + return actual +} + func TestCGo(t *testing.T) { var cflags = []string{"--target=armv6m-none-eabi"} @@ -74,7 +91,7 @@ func TestCGo(t *testing.T) { if err != nil { t.Errorf("could not write out CGo AST: %v", err) } - actual := strings.Replace(string(buf.Bytes()), "\r\n", "\n", -1) + actual := normalizeResult(string(buf.Bytes())) // Read the file with the expected output, to compare against. outfile := filepath.Join("testdata", name+".out.go") diff --git a/cgo/testdata/types.out.go b/cgo/testdata/types.out.go index 8a750080bb..af638b9e74 100644 --- a/cgo/testdata/types.out.go +++ b/cgo/testdata/types.out.go @@ -62,12 +62,18 @@ type C.union3_t = C.union_1 type C.union_nested_t = C.union_3 type C.unionarray_t = struct{ arr [10]C.uchar } -func (s *C.struct_4) bitfield_a() C.uchar { return s.__bitfield_1 & 0x1f } -func (s *C.struct_4) set_bitfield_a(value C.uchar) { s.__bitfield_1 = s.__bitfield_1&^0x1f | value&0x1f<<0 } +func (s *C.struct_4) bitfield_a() C.uchar { + return s.__bitfield_1 & 0x1f +} +func (s *C.struct_4) set_bitfield_a(value C.uchar) { + s.__bitfield_1 = s.__bitfield_1&^0x1f | value&0x1f<<0 +} func (s *C.struct_4) bitfield_b() C.uchar { return s.__bitfield_1 >> 5 & 0x1 } -func (s *C.struct_4) set_bitfield_b(value C.uchar) { s.__bitfield_1 = s.__bitfield_1&^0x20 | value&0x1<<5 } +func (s *C.struct_4) set_bitfield_b(value C.uchar) { + s.__bitfield_1 = s.__bitfield_1&^0x20 | value&0x1<<5 +} func (s *C.struct_4) bitfield_c() C.uchar { return s.__bitfield_1 >> 6 } @@ -94,25 +100,45 @@ type C.struct_type1 struct { } type C.struct_type2 struct{ _type C.int } -func (union *C.union_1) unionfield_i() *C.int { return (*C.int)(unsafe.Pointer(&union.$union)) } -func (union *C.union_1) unionfield_d() *float64 { return (*float64)(unsafe.Pointer(&union.$union)) } -func (union *C.union_1) unionfield_s() *C.short { return (*C.short)(unsafe.Pointer(&union.$union)) } +func (union *C.union_1) unionfield_i() *C.int { + return (*C.int)(unsafe.Pointer(&union.$union)) +} +func (union *C.union_1) unionfield_d() *float64 { + return (*float64)(unsafe.Pointer(&union.$union)) +} +func (union *C.union_1) unionfield_s() *C.short { + return (*C.short)(unsafe.Pointer(&union.$union)) +} type C.union_1 struct{ $union uint64 } -func (union *C.union_2) unionfield_area() *C.point2d_t { return (*C.point2d_t)(unsafe.Pointer(&union.$union)) } -func (union *C.union_2) unionfield_solid() *C.point3d_t { return (*C.point3d_t)(unsafe.Pointer(&union.$union)) } +func (union *C.union_2) unionfield_area() *C.point2d_t { + return (*C.point2d_t)(unsafe.Pointer(&union.$union)) +} +func (union *C.union_2) unionfield_solid() *C.point3d_t { + return (*C.point3d_t)(unsafe.Pointer(&union.$union)) +} type C.union_2 struct{ $union [3]uint32 } -func (union *C.union_3) unionfield_point() *C.point3d_t { return (*C.point3d_t)(unsafe.Pointer(&union.$union)) } -func (union *C.union_3) unionfield_array() *C.unionarray_t { return (*C.unionarray_t)(unsafe.Pointer(&union.$union)) } -func (union *C.union_3) unionfield_thing() *C.union3_t { return (*C.union3_t)(unsafe.Pointer(&union.$union)) } +func (union *C.union_3) unionfield_point() *C.point3d_t { + return (*C.point3d_t)(unsafe.Pointer(&union.$union)) +} +func (union *C.union_3) unionfield_array() *C.unionarray_t { + return (*C.unionarray_t)(unsafe.Pointer(&union.$union)) +} +func (union *C.union_3) unionfield_thing() *C.union3_t { + return (*C.union3_t)(unsafe.Pointer(&union.$union)) +} type C.union_3 struct{ $union [2]uint64 } -func (union *C.union_union2d) unionfield_i() *C.int { return (*C.int)(unsafe.Pointer(&union.$union)) } -func (union *C.union_union2d) unionfield_d() *[2]float64 { return (*[2]float64)(unsafe.Pointer(&union.$union)) } +func (union *C.union_union2d) unionfield_i() *C.int { + return (*C.int)(unsafe.Pointer(&union.$union)) +} +func (union *C.union_union2d) unionfield_d() *[2]float64 { + return (*[2]float64)(unsafe.Pointer(&union.$union)) +} type C.union_union2d struct{ $union [2]uint64 } type C.enum_option C.int diff --git a/main_test.go b/main_test.go index f91ed06f2a..36f96ba069 100644 --- a/main_test.go +++ b/main_test.go @@ -123,7 +123,7 @@ func runTest(path, target string, t *testing.T) { PrintIR: false, DumpSSA: false, VerifyIR: true, - Debug: false, + Debug: true, PrintSizes: "", WasmAbi: "js", }