aboutsummaryrefslogtreecommitdiffstats
path: root/pkg/compiler
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2018-01-23 11:38:53 +0100
committerDmitry Vyukov <dvyukov@google.com>2018-01-23 11:38:53 +0100
commit3d76cc40d99e9f984db1ecc9310a8ea2004ec901 (patch)
treef80644ea1b67d6a9d9c5475c7d3737082c866102 /pkg/compiler
parent14d1e424b6a582d021c73c88e1f0c5f0962ecc9d (diff)
pkg/compiler: fix len of parent template struct
Consider the following example: type len_templ1[DATA1, DATA2] { data DATA1 inner len_temp2[DATA2] } type len_temp2[DATA] { data DATA len len[len_templ1, int8] } Here len refers to a parent struct, but the struct is a template, so it's actual name is something like "len_templ1[int8, int16]". Currently this does not work as compiler barks at incorrect len target. Make this work.
Diffstat (limited to 'pkg/compiler')
-rw-r--r--pkg/compiler/check.go15
-rw-r--r--pkg/compiler/testdata/all.txt14
2 files changed, 26 insertions, 3 deletions
diff --git a/pkg/compiler/check.go b/pkg/compiler/check.go
index eb2a13e19..1954fded5 100644
--- a/pkg/compiler/check.go
+++ b/pkg/compiler/check.go
@@ -7,6 +7,7 @@ package compiler
import (
"fmt"
+ "strings"
"github.com/google/syzkaller/pkg/ast"
"github.com/google/syzkaller/prog"
@@ -268,14 +269,15 @@ func (comp *compiler) checkLenType(t *ast.Type, name string, fields []*ast.Field
for i, arg := range args {
argDesc := desc.Args[i]
if argDesc.Type == typeArgLenTarget {
- comp.checkLenTarget(t, name, arg.Ident, fields, parents)
+ comp.checkLenTarget(t, name, &arg.Ident, fields, parents)
} else if argDesc.Type == typeArgType {
comp.checkLenType(arg, name, fields, parents, checked, false)
}
}
}
-func (comp *compiler) checkLenTarget(t *ast.Type, name, target string, fields []*ast.Field, parents []*ast.Struct) {
+func (comp *compiler) checkLenTarget(t *ast.Type, name string, targetp *string, fields []*ast.Field, parents []*ast.Struct) {
+ target := *targetp
if target == name {
comp.error(t.Pos, "%v target %v refer to itself", t.Ident, target)
return
@@ -311,7 +313,14 @@ func (comp *compiler) checkLenTarget(t *ast.Type, name, target string, fields []
return
}
for _, parent := range parents {
- if target == parent.Name.Name {
+ parentName := parent.Name.Name
+ if pos := strings.IndexByte(parentName, '['); pos != -1 {
+ // For template parents name is "struct_name[ARG1, ARG2]",
+ // strip the part after '[' and update actual len target.
+ parentName = parentName[:pos]
+ }
+ if target == parentName {
+ *targetp = parent.Name.Name
return
}
}
diff --git a/pkg/compiler/testdata/all.txt b/pkg/compiler/testdata/all.txt
index 88e45dba4..8bd81c7d4 100644
--- a/pkg/compiler/testdata/all.txt
+++ b/pkg/compiler/testdata/all.txt
@@ -29,6 +29,20 @@ proc_struct1 {
f1 proc[C0, 8, int8]
}
+# Len/bytesize types.
+
+type len_templ1[DATA1, DATA2] {
+ data DATA1
+ inner len_temp2[DATA2]
+}
+
+type len_temp2[DATA] {
+ data DATA
+ len len[len_templ1, int8]
+}
+
+foo$len_templ(a ptr[in, len_templ1[int8, int16]])
+
# Void type.
void0 {