aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Chaignon <paul.chaignon@gmail.com>2024-03-01 17:02:06 +0100
committerAleksandr Nogikh <nogikh@google.com>2024-03-01 17:12:18 +0000
commit25905f5d0a2a7883bd33491997556193582c6059 (patch)
treec794c7e216531861542cfeb66f89ae26480b819d
parent83acf9e00cea13b199346aea4d72094a03cef0ca (diff)
compiler: support using int flags in field conditions
Commit ed571339c6ff ("pkg/compiler: support if[expr] attributes") added support for conditional fields in structs and unions. Conditions however cannot refer to flags, as in the following example: struct { f0 flags[some_flags, int32] f1 int32 (if[value[f0] & FLAG1]) } [packed] It will fail to compile with: flags does not refer to an integer This commit adds support for that syntax. Signed-off-by: Paul Chaignon <paul.chaignon@gmail.com>
-rw-r--r--pkg/ast/testdata/all.txt5
-rw-r--r--pkg/compiler/check.go4
-rw-r--r--pkg/compiler/testdata/errors2.txt4
3 files changed, 8 insertions, 5 deletions
diff --git a/pkg/ast/testdata/all.txt b/pkg/ast/testdata/all.txt
index d04fd4992..a274b3eff 100644
--- a/pkg/ast/testdata/all.txt
+++ b/pkg/ast/testdata/all.txt
@@ -16,8 +16,11 @@ expressions {
f3 int8 (if[X & (A == B) & Z != C])
}
+intflags = 1, 2, 3, 4
+
condFields {
mask int8
+ flags flags[intflags, int8]
# Simple expressions work.
f0 int16 (if[val[mask] == SOME_CONST])
# Conditions and other attributes work together.
@@ -25,5 +28,5 @@ condFields {
# Test some more complex expressions.
f2 int16 (out, if[val[mask] & SOME_CONST == OTHER_CONST])
f3 int16 (out, if[val[mask] & SOME_CONST & OTHER_CONST == val[mask] & CONST_X])
- f4 int16 (out, if[val[mask] & SOME_CONST])
+ f4 int16 (out, if[val[flags] & SOME_CONST])
}
diff --git a/pkg/compiler/check.go b/pkg/compiler/check.go
index 3f340a660..103b69eb5 100644
--- a/pkg/compiler/check.go
+++ b/pkg/compiler/check.go
@@ -650,8 +650,8 @@ func (comp *compiler) checkPathField(target, t *ast.Type, field *ast.Field) bool
func (comp *compiler) checkExprLastField(target *ast.Type, field *ast.Field) {
_, desc := comp.derefPointers(field.Type)
- if desc != typeInt {
- comp.error(target.Pos, "%v does not refer to an integer", field.Name.Name)
+ if desc != typeInt && desc != typeFlags {
+ comp.error(target.Pos, "%v does not refer to an integer or a flag", field.Name.Name)
}
}
diff --git a/pkg/compiler/testdata/errors2.txt b/pkg/compiler/testdata/errors2.txt
index 0f10ea278..ffb2e5bc5 100644
--- a/pkg/compiler/testdata/errors2.txt
+++ b/pkg/compiler/testdata/errors2.txt
@@ -470,11 +470,11 @@ conditional_fields {
f3 some_nested_flags
f4 int32 (if[value[f3:f1] != 0])
f5 int32 (if[value[f3:f2:f4] != 0]) ### value path f2 does not refer to a struct
- f6 int32 (if[value[f3:f4] != 0]) ### f4 does not refer to an integer
+ f6 int32 (if[value[f3:f4] != 0]) ### f4 does not refer to an integer or a flag
f7 int32 (if[value[f3:some_field] != 0]) ### value target some_field does not exist in some_nested_flags
f8 int32 (if[value[f3:f5] != 0]) ### f5 has conditions, so value path cannot reference it
f9 int32 (if[value[parent:a] != 0]) ### value target a does not exist in conditional_fields
- f10 int32 (if[value[f3:f6] != 0]) ### f6 does not refer to an integer
+ f10 int32 (if[value[f3:f6] != 0]) ### f6 does not refer to an integer or a flag
f11 len[f2, int32] ### f2 has conditions, so len path cannot reference it
f12 union_cond_fields
f13 int32:8 (if[1]) ### bitfields may not have conditions