aboutsummaryrefslogtreecommitdiffstats
path: root/pkg/compiler
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2018-07-09 20:47:07 +0200
committerDmitry Vyukov <dvyukov@google.com>2018-07-09 20:47:07 +0200
commit710eefe85a976c438da255499fbefd1a6c989ef6 (patch)
tree3467ac95a3c574bdf41105e012df2e4c540ed859 /pkg/compiler
parentf25e57704183544b0d540ef0035acfa6fb9071d7 (diff)
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.
Diffstat (limited to 'pkg/compiler')
-rw-r--r--pkg/compiler/testdata/all.txt6
-rw-r--r--pkg/compiler/testdata/errors.txt1
-rw-r--r--pkg/compiler/testdata/errors2.txt5
-rw-r--r--pkg/compiler/types.go44
4 files changed, 41 insertions, 15 deletions
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<<size {
- comp.error(args[0].Pos, "values starting from %v overflow base type", start)
- } else if start+maxPids*perProc > 1<<size {
- comp.error(args[0].Pos, "values starting from %v with step %v overflow base type for %v procs",
- start, perProc, maxPids)
- }
+ max := uint64(1) << size
+ if size == 64 {
+ max = ^uint64(0)
+ }
+ const maxPids = 32 // executor knows about this constant (MAX_PIDS)
+ if start >= 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",