From 3d76cc40d99e9f984db1ecc9310a8ea2004ec901 Mon Sep 17 00:00:00 2001 From: Dmitry Vyukov Date: Tue, 23 Jan 2018 11:38:53 +0100 Subject: 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. --- pkg/compiler/check.go | 15 ++++++++++++--- pkg/compiler/testdata/all.txt | 14 ++++++++++++++ 2 files changed, 26 insertions(+), 3 deletions(-) (limited to 'pkg/compiler') 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 { -- cgit mrf-deployment