From 710eefe85a976c438da255499fbefd1a6c989ef6 Mon Sep 17 00:00:00 2001 From: Dmitry Vyukov Date: Mon, 9 Jul 2018 20:47:07 +0200 Subject: pkg/compiler: support negative integers Currently we have to use 0xffffffffffffffff to represent -1, and we can't express e.g. -20:20 int range. Support negative consts to fix both problems. --- pkg/compiler/testdata/all.txt | 6 ++++-- pkg/compiler/testdata/errors.txt | 1 + pkg/compiler/testdata/errors2.txt | 5 +++++ pkg/compiler/types.go | 44 +++++++++++++++++++++++++++------------ 4 files changed, 41 insertions(+), 15 deletions(-) (limited to 'pkg/compiler') diff --git a/pkg/compiler/testdata/all.txt b/pkg/compiler/testdata/all.txt index 573fb6412..6fff34284 100644 --- a/pkg/compiler/testdata/all.txt +++ b/pkg/compiler/testdata/all.txt @@ -7,7 +7,9 @@ foo$2(a ptr[out, array[int32]]) foo$3(a union_arg) foo$4() r0 foo$5(a int8['a':'z']) -foo$6(a ptr[in, strings]) +foo$6(a int8[-20:-10]) +foo$7(a int8[-20:20]) +foo$8(a ptr[in, strings]) resource r0[intptr] @@ -38,7 +40,7 @@ strings { string_flags1 = "foo", "barbaz" string_flags2 = "" -int_flags = 0, 1 +int_flags = 0, 1, 0xabc, 'x', -11 _ = 1, 2 _ = C1, C2 diff --git a/pkg/compiler/testdata/errors.txt b/pkg/compiler/testdata/errors.txt index cbfebbfd7..3c2cb57ae 100644 --- a/pkg/compiler/testdata/errors.txt +++ b/pkg/compiler/testdata/errors.txt @@ -329,4 +329,5 @@ foo$fmt4(a ptr[in, fmt[dec, int8:3]]) ### unexpected ':', only struct fields ca struct$fmt0 { f0 fmt[dec, int8:3] ### unexpected ':', only struct fields can be bitfields + f1 int32:-1 ### bitfield of size 18446744073709551615 is too large for base type of size 32 } diff --git a/pkg/compiler/testdata/errors2.txt b/pkg/compiler/testdata/errors2.txt index 1b1adefa5..77db29197 100644 --- a/pkg/compiler/testdata/errors2.txt +++ b/pkg/compiler/testdata/errors2.txt @@ -217,6 +217,11 @@ foo$507(a ptr[in, array[int32, 0:0]]) ### arrays of size 0 are not supported foo$508(a ptr[in, string["foo", 3]]) ### string value "foo\x00" exceeds buffer length 3 foo$509(a int8['b':'a']) ### bad int range [98:97] foo$510(a type500) +foo$511(a int32[-10:-20]) ### bad int range [18446744073709551606:18446744073709551596] +foo$512(a ptr[in, array[int8, -2:-1]]) ### bad size range [18446744073709551614:18446744073709551615] +foo$513(a ptr[in, array[int8, -2:2]]) ### bad size range [18446744073709551614:2] +foo$514(a vma[-2:2]) ### bad size range [18446744073709551614:2] +foo$515(a ptr[in, proc[1, -10, int64]]) ### values starting from 1 with step 18446744073709551606 overflow base type for 32 procs type type500 proc[C1, 8, int8] ### values starting from 1 with step 8 overflow base type for 32 procs type type501 int8 ### unused type type501 diff --git a/pkg/compiler/types.go b/pkg/compiler/types.go index 156b1505a..293496a9c 100644 --- a/pkg/compiler/types.go +++ b/pkg/compiler/types.go @@ -68,7 +68,7 @@ var typeInt = &typeDesc{ AllowColon: true, ResourceBase: true, OptArgs: 1, - Args: []namedArg{{Name: "range", Type: typeArgRange}}, + Args: []namedArg{{Name: "range", Type: typeArgIntRange}}, Check: func(comp *compiler, t *ast.Type, args []*ast.Type, base prog.IntTypeCommon) { typeArgBase.Type.Check(comp, t) }, @@ -128,7 +128,7 @@ var typeArray = &typeDesc{ CanBeTypedef: true, CantBeOpt: true, OptArgs: 1, - Args: []namedArg{{Name: "type", Type: typeArgType}, {Name: "size", Type: typeArgRange}}, + Args: []namedArg{{Name: "type", Type: typeArgType}, {Name: "size", Type: typeArgSizeRange}}, CheckConsts: func(comp *compiler, t *ast.Type, args []*ast.Type, base prog.IntTypeCommon) { if len(args) > 1 && args[1].Value == 0 && args[1].Value2 == 0 { comp.error(args[1].Pos, "arrays of size 0 are not supported") @@ -290,7 +290,7 @@ var typeVMA = &typeDesc{ Names: []string{"vma"}, CanBeArgRet: canBeArg, OptArgs: 1, - Args: []namedArg{{Name: "size range", Type: typeArgRange}}, + Args: []namedArg{{Name: "size range", Type: typeArgSizeRange}}, Gen: func(comp *compiler, t *ast.Type, args []*ast.Type, base prog.IntTypeCommon) prog.Type { begin, end := uint64(0), uint64(0) if len(args) > 0 { @@ -367,14 +367,16 @@ var typeProc = &typeDesc{ return } size := base.TypeSize * 8 - if size != 64 { - const maxPids = 32 // executor knows about this constant (MAX_PIDS) - if start >= 1< 1<= max { + comp.error(args[0].Pos, "values starting from %v overflow base type", start) + } else if perProc > (max-start)/maxPids { + comp.error(args[0].Pos, "values starting from %v with step %v overflow base type for %v procs", + start, perProc, maxPids) } }, Gen: func(comp *compiler, t *ast.Type, args []*ast.Type, base prog.IntTypeCommon) prog.Type { @@ -763,19 +765,35 @@ var typeArgInt = &typeArg{ Kind: kindInt, } -var typeArgRange = &typeArg{ +var typeArgIntRange = &typeArg{ Kind: kindInt, AllowColon: true, CheckConsts: func(comp *compiler, t *ast.Type) { if !t.HasColon { t.Value2 = t.Value + t.Value2Fmt = t.ValueFmt } - if t.Value > t.Value2 { + if t.Value2-t.Value > 1<<64-1<<32 { comp.error(t.Pos, "bad int range [%v:%v]", t.Value, t.Value2) } }, } +// Size of array and vma's. +var typeArgSizeRange = &typeArg{ + Kind: kindInt, + AllowColon: true, + CheckConsts: func(comp *compiler, t *ast.Type) { + if !t.HasColon { + t.Value2 = t.Value + } + const maxVal = 1e6 + if t.Value > t.Value2 || t.Value > maxVal || t.Value2 > maxVal { + comp.error(t.Pos, "bad size range [%v:%v]", t.Value, t.Value2) + } + }, +} + // Base type of const/len/etc. Same as typeInt, but can't have range. var typeArgBase = namedArg{ Name: "base type", -- cgit mrf-deployment