From 291192c61b4d6bad6c11e8732be7de26f1add0ef Mon Sep 17 00:00:00 2001 From: Dmitry Vyukov Date: Mon, 4 Sep 2017 19:52:57 +0200 Subject: [PATCH] pkg/compiler: don't allow bitfields in unions, args and anon types --- pkg/compiler/check.go | 24 +++++++++++++++--------- pkg/compiler/testdata/errors.txt | 10 ++++++++-- 2 files changed, 23 insertions(+), 11 deletions(-) diff --git a/pkg/compiler/check.go b/pkg/compiler/check.go index 5a3dea45..f75c0276 100644 --- a/pkg/compiler/check.go +++ b/pkg/compiler/check.go @@ -146,18 +146,18 @@ func (comp *compiler) checkTypes() { for _, decl := range comp.desc.Nodes { switch n := decl.(type) { case *ast.Resource: - comp.checkType(n.Base, false, false, true) + comp.checkType(n.Base, false, false, false, true) case *ast.Struct: for _, f := range n.Fields { - comp.checkType(f.Type, false, false, false) + comp.checkType(f.Type, false, false, !n.IsUnion, false) } comp.checkStruct(n) case *ast.Call: for _, a := range n.Args { - comp.checkType(a.Type, true, false, false) + comp.checkType(a.Type, true, false, false, false) } if n.Ret != nil { - comp.checkType(n.Ret, true, true, false) + comp.checkType(n.Ret, true, true, false, false) } } } @@ -394,7 +394,7 @@ func (comp *compiler) checkStruct(n *ast.Struct) { } } -func (comp *compiler) checkType(t *ast.Type, isArg, isRet, isResourceBase bool) { +func (comp *compiler) checkType(t *ast.Type, isArg, isRet, isStruct, isResourceBase bool) { if unexpected, _, ok := checkTypeKind(t, kindIdent); !ok { comp.error(t.Pos, "unexpected %v, expect type", unexpected) return @@ -404,9 +404,15 @@ func (comp *compiler) checkType(t *ast.Type, isArg, isRet, isResourceBase bool) comp.error(t.Pos, "unknown type %v", t.Ident) return } - if t.HasColon && (!desc.AllowColon || isArg) { - comp.error(t.Pos2, "unexpected ':'") - return + if t.HasColon { + if !desc.AllowColon { + comp.error(t.Pos2, "unexpected ':'") + return + } + if !isStruct { + comp.error(t.Pos2, "unexpected ':', only struct fields can be bitfields") + return + } } if isRet && (!desc.CanBeArg || desc.CantBeRet) { comp.error(t.Pos, "%v can't be syscall return", t.Ident) @@ -448,7 +454,7 @@ func (comp *compiler) checkType(t *ast.Type, isArg, isRet, isResourceBase bool) err0 := comp.errors for i, arg := range args { if desc.Args[i].Type == typeArgType { - comp.checkType(arg, false, isRet, false) + comp.checkType(arg, false, isRet, false, false) } else { comp.checkTypeArg(t, arg, desc.Args[i]) } diff --git a/pkg/compiler/testdata/errors.txt b/pkg/compiler/testdata/errors.txt index dc535b00..512d615c 100644 --- a/pkg/compiler/testdata/errors.txt +++ b/pkg/compiler/testdata/errors.txt @@ -63,7 +63,7 @@ sf2 = "a", "b" sf2 = "c" ### string flags sf2 redeclared, previously declared at errors.txt:62:1 resource r2[r0]: 2 -resource r3[int32:1] +resource r3[int32:1] ### unexpected ':', only struct fields can be bitfields resource r4[int32[opt]] ### resource base can't be marked as opt resource r5[non_existent] ### unknown type non_existent resource r9["foo"] ### unexpected string "foo", expect type @@ -108,7 +108,8 @@ foo$43(a ptr[in, string[1]]) ### unexpected int 1, string arg must be a string l foo$44(a int32) len[a] ### len can't be syscall return foo$45(a int32) len[b] ### len can't be syscall return foo$46(a ptr[in, in]) ### unknown type in -foo$47(a int32:2) ### unexpected ':' +foo$47(a int32:2) ### unexpected ':', only struct fields can be bitfields +foo$48(a ptr[in, int32:7]) ### unexpected ':', only struct fields can be bitfields opt { ### struct uses reserved name opt f1 int32 @@ -162,6 +163,11 @@ u4 [ f2 int32 ] [packed] ### unknown union u4 attribute packed +u5 [ + f1 int8:1 ### unexpected ':', only struct fields can be bitfields + f2 int8:2 ### unexpected ':', only struct fields can be bitfields +] + define d0 SOMETHING define d1 `some C expression` define d2 some C expression