From 22535fecd5b37c6a14b92b17e548c8061ef77924 Mon Sep 17 00:00:00 2001 From: Dmitry Vyukov Date: Sat, 18 Jan 2020 14:25:14 +0100 Subject: pkg/compiler: don't mark flags with 0 as bitmask They can't be a bitmask. This fixes important cases of "0, 1" and "0, 1, 2" flags. Fix some descriptions that added 0 to bitmasks explicitly (we should do it automatically instead). --- pkg/compiler/types.go | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) (limited to 'pkg') diff --git a/pkg/compiler/types.go b/pkg/compiler/types.go index 8b3b97101..43efee202 100644 --- a/pkg/compiler/types.go +++ b/pkg/compiler/types.go @@ -313,16 +313,7 @@ var typeFlags = &typeDesc{ name := args[0].Ident base.TypeName = name f := comp.intFlags[name] - bitmask := true - var combined uint64 values := genIntArray(f.Values) - for _, v := range values { - if v&combined != 0 { - bitmask = false - break - } - combined |= v - } if len(values) == 0 || len(values) == 1 && values[0] == 0 { // We can get this if all values are unsupported consts. // Also generate const[0] if we have only 1 flags value which is 0, @@ -339,11 +330,28 @@ var typeFlags = &typeDesc{ return &prog.FlagsType{ IntTypeCommon: base, Vals: values, - BitMask: bitmask, + BitMask: isBitmask(values), } }, } +func isBitmask(values []uint64) bool { + if values[0] == 0 { + // 0 can't be part of bitmask, this helps to handle important + // case like "0, 1" and "0, 1, 2" that would be detected + // as bitmask otherwise. + return false + } + var combined uint64 + for _, v := range values { + if v&combined != 0 { + return false + } + combined |= v + } + return true +} + var typeArgFlags = &typeArg{ Kind: kindIdent, Check: func(comp *compiler, t *ast.Type) { -- cgit mrf-deployment