pkg/compiler: don't allow bitfields in unions, args and anon types

This commit is contained in:
Dmitry Vyukov 2017-09-04 19:52:57 +02:00
parent e707c97f9a
commit 291192c61b
2 changed files with 23 additions and 11 deletions

View File

@ -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])
}

View File

@ -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