diff options
| author | Paul Chaignon <paul.chaignon@gmail.com> | 2023-12-01 13:09:24 +0100 |
|---|---|---|
| committer | Aleksandr Nogikh <nogikh@google.com> | 2023-12-05 13:40:28 +0000 |
| commit | 781340bec8eda54d9d8edbd09dde6f7454911ce4 (patch) | |
| tree | 711208235d99763525e615c40900aef9c479fb62 /pkg/compiler | |
| parent | 8b813e96b14493924eb3dc4f0c323508fe3f8ddd (diff) | |
compiler: error on circular dependencies in flag definitions
To detect those circular dependencies, we simply keep track of which
flags we already visited when flattening the flags definition.
Suggested-by: Aleksandr Nogikh <nogikh@google.com>
Signed-off-by: Paul Chaignon <paul.chaignon@gmail.com>
Diffstat (limited to 'pkg/compiler')
| -rw-r--r-- | pkg/compiler/compiler.go | 13 | ||||
| -rw-r--r-- | pkg/compiler/testdata/errors.txt | 6 |
2 files changed, 16 insertions, 3 deletions
diff --git a/pkg/compiler/compiler.go b/pkg/compiler/compiler.go index 3c5dea1d1..2e13988b7 100644 --- a/pkg/compiler/compiler.go +++ b/pkg/compiler/compiler.go @@ -361,7 +361,7 @@ func arrayContains(a []string, v string) bool { func (comp *compiler) flattenFlags() { for name, flags := range comp.intFlags { - if err := comp.recurFlattenFlags(name, flags); err != nil { + if err := comp.recurFlattenFlags(name, flags, map[string]bool{}); err != nil { comp.error(flags.Pos, "%v", err) } } @@ -379,11 +379,18 @@ func (comp *compiler) flattenFlags() { } } -func (comp *compiler) recurFlattenFlags(name string, flags *ast.IntFlags) error { +func (comp *compiler) recurFlattenFlags(name string, flags *ast.IntFlags, visitedFlags map[string]bool) error { + if _, visited := visitedFlags[name]; visited { + return fmt.Errorf("flags %v used twice or circular dependency on %v", name, name) + } + visitedFlags[name] = true + var values []*ast.Int for _, flag := range flags.Values { if f, isFlags := comp.intFlags[flag.Ident]; isFlags { - comp.recurFlattenFlags(flag.Ident, f) + if err := comp.recurFlattenFlags(flag.Ident, f, visitedFlags); err != nil { + return err + } values = append(values, comp.intFlags[flag.Ident].Values...) } else { values = append(values, flag) diff --git a/pkg/compiler/testdata/errors.txt b/pkg/compiler/testdata/errors.txt index 321ff8daf..47d343e36 100644 --- a/pkg/compiler/testdata/errors.txt +++ b/pkg/compiler/testdata/errors.txt @@ -97,6 +97,12 @@ f3000 = 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, nested_flags(a flags[f1000], b flags[f1100]) +f110 = 1, 2, 3, 4, f120 ### flags f110 used twice or circular dependency on f110 +f120 = 10, 11, 12, f130 ### flags f120 used twice or circular dependency on f120 +f130 = 100, 110, f110 ### flags f130 used twice or circular dependency on f130 + +loop_flags(a flags[f110]) + resource r2[r0]: 2 resource r3[int32:1] ### unexpected ':', only struct fields can be bitfields resource r4[int32[opt]] ### resource base can't be marked as opt |
