aboutsummaryrefslogtreecommitdiffstats
path: root/pkg/compiler/check.go
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2019-05-14 16:21:19 +0200
committerDmitry Vyukov <dvyukov@google.com>2019-05-14 19:28:01 +0200
commit2376f0f937b8e6b457ef1fdf088b8b7059dcb0e2 (patch)
tree6a66d085190a488475a843ec8a138fd6a3c8e8a1 /pkg/compiler/check.go
parent9a4969814ea6a65b306ca7d3192c23381c778ad4 (diff)
pkg/compiler: allow to refer to syscall arguments in len paths
This allows to use len[syscall:arg] expressions.
Diffstat (limited to 'pkg/compiler/check.go')
-rw-r--r--pkg/compiler/check.go34
1 files changed, 21 insertions, 13 deletions
diff --git a/pkg/compiler/check.go b/pkg/compiler/check.go
index 8442f70ec..0b296e2ea 100644
--- a/pkg/compiler/check.go
+++ b/pkg/compiler/check.go
@@ -179,7 +179,7 @@ func (comp *compiler) checkFieldGroup(fields []*ast.Field, what, ctx string) {
existing := make(map[string]bool)
for _, f := range fields {
fn := f.Name.Name
- if fn == prog.ParentRef {
+ if fn == prog.ParentRef || fn == prog.SyscallRef {
comp.error(f.Pos, "reserved %v name %v in %v", what, fn, ctx)
}
if existing[fn] {
@@ -347,10 +347,18 @@ func (comp *compiler) checkLenType(t0, t *ast.Type, parents []parentDesc,
func (comp *compiler) checkLenTarget(arg, t0, t *ast.Type, parents []parentDesc, warned map[string]bool) {
targets := append([]*ast.Type{arg}, arg.Colon...)
- if len(targets) != 1 {
- for _, target := range targets {
- if target.Ident == prog.ParentRef {
- comp.error(target.Pos, "%v can't be part of path expressions", prog.ParentRef)
+ for i, target := range targets {
+ if target.Ident == prog.ParentRef && len(targets) != 1 {
+ comp.error(target.Pos, "%v can't be part of path expressions", prog.ParentRef)
+ return
+ }
+ if target.Ident == prog.SyscallRef {
+ if i != 0 {
+ comp.error(target.Pos, "syscall can't be in the middle of path expressions")
+ return
+ }
+ if len(targets) == 1 {
+ comp.error(targets[0].Pos, "no argument name after syscall reference")
return
}
}
@@ -405,15 +413,15 @@ func (comp *compiler) checkLenTargetRec(t0, t *ast.Type, targets []*ast.Type,
}
for pi := len(parents) - 1; pi >= 0; pi-- {
parent := parents[pi]
- if parent.name == "" || parent.name != target.Ident && target.Ident != prog.ParentRef {
- continue
- }
- if len(targets) != 0 {
- parents1 := make([]parentDesc, pi+1)
- copy(parents1, parents[:pi+1])
- comp.checkLenTargetRec(t0, t, targets, parents1, warned)
+ if parent.name != "" && (parent.name == target.Ident || target.Ident == prog.ParentRef) ||
+ parent.name == "" && target.Ident == prog.SyscallRef {
+ if len(targets) != 0 {
+ parents1 := make([]parentDesc, pi+1)
+ copy(parents1, parents[:pi+1])
+ comp.checkLenTargetRec(t0, t, targets, parents1, warned)
+ }
+ return
}
- return
}
comp.error(target.Pos, "%v target %v does not exist", t.Ident, target.Ident)
}