aboutsummaryrefslogtreecommitdiffstats
path: root/pkg
diff options
context:
space:
mode:
Diffstat (limited to 'pkg')
-rw-r--r--pkg/ast/filter.go14
-rw-r--r--pkg/compiler/check.go75
-rw-r--r--pkg/compiler/compiler.go17
3 files changed, 71 insertions, 35 deletions
diff --git a/pkg/ast/filter.go b/pkg/ast/filter.go
new file mode 100644
index 000000000..a36114e82
--- /dev/null
+++ b/pkg/ast/filter.go
@@ -0,0 +1,14 @@
+// Copyright 2018 syzkaller project authors. All rights reserved.
+// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
+
+package ast
+
+func (desc *Description) Filter(predicate func(Node) bool) *Description {
+ desc1 := &Description{}
+ for _, n := range desc.Nodes {
+ if predicate(n) {
+ desc1.Nodes = append(desc1.Nodes, n.Clone())
+ }
+ }
+ return desc1
+}
diff --git a/pkg/compiler/check.go b/pkg/compiler/check.go
index 7b4b63fa8..087075a12 100644
--- a/pkg/compiler/check.go
+++ b/pkg/compiler/check.go
@@ -11,6 +11,7 @@ import (
"github.com/google/syzkaller/pkg/ast"
"github.com/google/syzkaller/prog"
+ "github.com/google/syzkaller/sys/targets"
)
func (comp *compiler) typecheck() {
@@ -371,6 +372,48 @@ func (comp *compiler) checkLenTarget(t *ast.Type, name, target string, fields []
comp.error(t.Pos, "%v target %v does not exist", t.Ident, target)
}
+func CollectUnused(desc *ast.Description, target *targets.Target) []ast.Node {
+ comp := createCompiler(desc, target, nil)
+ comp.typecheck()
+ return comp.collectUnused()
+}
+
+func (comp *compiler) collectUnused() []ast.Node {
+ var unused []ast.Node
+
+ comp.used, _, _ = comp.collectUsed(false)
+ structs, flags, strflags := comp.collectUsed(true)
+ _, _, _ = structs, flags, strflags
+
+ for name, n := range comp.intFlags {
+ if !flags[name] {
+ unused = append(unused, n)
+ }
+ }
+ for name, n := range comp.strFlags {
+ if !strflags[name] && builtinStrFlags[name] == nil {
+ unused = append(unused, n)
+ }
+ }
+ for name, n := range comp.resources {
+ if !structs[name] {
+ unused = append(unused, n)
+ }
+ }
+ for name, n := range comp.structs {
+ if !structs[name] {
+ unused = append(unused, n)
+ }
+ }
+ for name, n := range comp.typedefs {
+ if !comp.usedTypedefs[name] {
+ unused = append(unused, n)
+ }
+ }
+
+ return unused
+}
+
func (comp *compiler) collectUsed(all bool) (structs, flags, strflags map[string]bool) {
structs = make(map[string]bool)
flags = make(map[string]bool)
@@ -432,35 +475,9 @@ func (comp *compiler) collectUsedType(structs, flags, strflags map[string]bool,
}
func (comp *compiler) checkUnused() {
- comp.used, _, _ = comp.collectUsed(false)
- structs, flags, strflags := comp.collectUsed(true)
- _, _, _ = structs, flags, strflags
-
- for name, n := range comp.intFlags {
- if !flags[name] {
- comp.error(n.Pos, "unused flags %v", name)
- }
- }
- for name, n := range comp.strFlags {
- if !strflags[name] && builtinStrFlags[name] == nil {
- comp.error(n.Pos, "unused string flags %v", name)
- }
- }
- for name, n := range comp.resources {
- if !structs[name] {
- comp.error(n.Pos, "unused resource %v", name)
- }
- }
- for name, n := range comp.structs {
- if !structs[name] {
- _, typ, _ := n.Info()
- comp.error(n.Pos, "unused %v %v", typ, name)
- }
- }
- for name, n := range comp.typedefs {
- if !comp.usedTypedefs[name] {
- comp.error(n.Pos, "unused type %v", name)
- }
+ for _, n := range comp.collectUnused() {
+ pos, typ, name := n.Info()
+ comp.error(pos, fmt.Sprintf("unused %v %v", typ, name))
}
}
diff --git a/pkg/compiler/compiler.go b/pkg/compiler/compiler.go
index e66da802b..2c4e81b2b 100644
--- a/pkg/compiler/compiler.go
+++ b/pkg/compiler/compiler.go
@@ -43,13 +43,9 @@ type Prog struct {
fileConsts map[string]*ConstInfo
}
-// Compile compiles sys description.
-func Compile(desc *ast.Description, consts map[string]uint64, target *targets.Target, eh ast.ErrorHandler) *Prog {
- if eh == nil {
- eh = ast.LoggingHandler
- }
+func createCompiler(desc *ast.Description, target *targets.Target, eh ast.ErrorHandler) *compiler {
comp := &compiler{
- desc: desc.Clone(),
+ desc: desc,
target: target,
eh: eh,
ptrSize: target.PtrSize,
@@ -72,6 +68,15 @@ func Compile(desc *ast.Description, consts map[string]uint64, target *targets.Ta
for name, n := range builtinStrFlags {
comp.strFlags[name] = n
}
+ return comp
+}
+
+// Compile compiles sys description.
+func Compile(desc *ast.Description, consts map[string]uint64, target *targets.Target, eh ast.ErrorHandler) *Prog {
+ if eh == nil {
+ eh = ast.LoggingHandler
+ }
+ comp := createCompiler(desc.Clone(), target, eh)
comp.typecheck()
// The subsequent, more complex, checks expect basic validity of the tree,
// in particular corrent number of type arguments. If there were errors,