aboutsummaryrefslogtreecommitdiffstats
path: root/pkg
diff options
context:
space:
mode:
Diffstat (limited to 'pkg')
-rw-r--r--pkg/compiler/check.go32
-rw-r--r--pkg/compiler/testdata/errors2.txt5
2 files changed, 27 insertions, 10 deletions
diff --git a/pkg/compiler/check.go b/pkg/compiler/check.go
index e8abc574e..9bb8c1c0c 100644
--- a/pkg/compiler/check.go
+++ b/pkg/compiler/check.go
@@ -547,16 +547,17 @@ type structDir struct {
}
func (comp *compiler) checkConstructors() {
- ctors := make(map[string]bool) // resources for which we have ctors
+ ctors := make(map[string]bool) // resources for which we have ctors
+ inputs := make(map[string]bool) // resources which are used as inputs
checked := make(map[structDir]bool)
for _, decl := range comp.desc.Nodes {
switch n := decl.(type) {
case *ast.Call:
for _, arg := range n.Args {
- comp.checkTypeCtors(arg.Type, prog.DirIn, true, ctors, checked)
+ comp.checkTypeCtors(arg.Type, prog.DirIn, true, ctors, inputs, checked)
}
if n.Ret != nil {
- comp.checkTypeCtors(n.Ret, prog.DirOut, true, ctors, checked)
+ comp.checkTypeCtors(n.Ret, prog.DirOut, true, ctors, inputs, checked)
}
}
}
@@ -564,17 +565,23 @@ func (comp *compiler) checkConstructors() {
switch n := decl.(type) {
case *ast.Resource:
name := n.Name.Name
- if !ctors[name] && comp.used[name] {
+ if !comp.used[name] {
+ continue
+ }
+ if !ctors[name] {
comp.error(n.Pos, "resource %v can't be created"+
- " (never mentioned as a syscall return value or output argument/field)",
- name)
+ " (never mentioned as a syscall return value or output argument/field)", name)
+ }
+ if !inputs[name] {
+ comp.error(n.Pos, "resource %v is never used as an input"+
+ "(such resources are not useful)", name)
}
}
}
}
func (comp *compiler) checkTypeCtors(t *ast.Type, dir prog.Dir, isArg bool,
- ctors map[string]bool, checked map[structDir]bool) {
+ ctors, inputs map[string]bool, checked map[structDir]bool) {
desc := comp.getTypeDesc(t)
if desc == typeResource {
// TODO(dvyukov): consider changing this to "dir == prog.DirOut".
@@ -589,6 +596,13 @@ func (comp *compiler) checkTypeCtors(t *ast.Type, dir prog.Dir, isArg bool,
r = comp.resources[r.Base.Ident]
}
}
+ if dir != prog.DirOut {
+ r := comp.resources[t.Ident]
+ for r != nil && !inputs[r.Name.Name] {
+ inputs[r.Name.Name] = true
+ r = comp.resources[r.Base.Ident]
+ }
+ }
return
}
if desc == typeStruct {
@@ -600,7 +614,7 @@ func (comp *compiler) checkTypeCtors(t *ast.Type, dir prog.Dir, isArg bool,
}
checked[key] = true
for _, fld := range s.Fields {
- comp.checkTypeCtors(fld.Type, dir, false, ctors, checked)
+ comp.checkTypeCtors(fld.Type, dir, false, ctors, inputs, checked)
}
return
}
@@ -610,7 +624,7 @@ func (comp *compiler) checkTypeCtors(t *ast.Type, dir prog.Dir, isArg bool,
_, args, _ := comp.getArgsBase(t, isArg)
for i, arg := range args {
if desc.Args[i].Type == typeArgType {
- comp.checkTypeCtors(arg, dir, desc.Args[i].IsArg, ctors, checked)
+ comp.checkTypeCtors(arg, dir, desc.Args[i].IsArg, ctors, inputs, checked)
}
}
}
diff --git a/pkg/compiler/testdata/errors2.txt b/pkg/compiler/testdata/errors2.txt
index fb69c8c5f..68b8a66df 100644
--- a/pkg/compiler/testdata/errors2.txt
+++ b/pkg/compiler/testdata/errors2.txt
@@ -11,6 +11,7 @@ resource r2[r1] ### recursive resource r2->r1->r2
resource r3[int32] ### unused resource r3
foo$0(a0 ptr[out, r0], a1 ptr[out, r1], a2 ptr[out, r2])
+foo$1(a0 r0, a1 r1, a2 r2)
# Recursive structs/unions.
@@ -175,9 +176,11 @@ resource r104[int8]
resource r105[int8]
resource r106[int8] ### resource r106 can't be created (never mentioned as a syscall return value or output argument/field)
resource r107[int8] ### resource r107 can't be created (never mentioned as a syscall return value or output argument/field)
+resource r108[int8] ### resource r108 is never used as an input(such resources are not useful)
-foo$300(a r100)
+foo$300(a0 r100, a1 r101, a2 r102, a3 r103, a4 r104)
foo$301(a ptr[out, array[r103]], b ptr[in, s300], c r107) r104
+foo$302() r108
s300 {
f1 ptr[inout, s301]