aboutsummaryrefslogtreecommitdiffstats
path: root/pkg/compiler
diff options
context:
space:
mode:
authorPaul Chaignon <paul.chaignon@gmail.com>2023-12-01 13:09:24 +0100
committerAleksandr Nogikh <nogikh@google.com>2023-12-05 13:40:28 +0000
commit781340bec8eda54d9d8edbd09dde6f7454911ce4 (patch)
tree711208235d99763525e615c40900aef9c479fb62 /pkg/compiler
parent8b813e96b14493924eb3dc4f0c323508fe3f8ddd (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.go13
-rw-r--r--pkg/compiler/testdata/errors.txt6
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