Как проверить корретность битовой маски?
У вас не битовая маска, так как b и c содержат один и тот же бит 2 и отличить c от b|c невозможно. 2|6 === 6. В битовой маске все уникальные некомбинированные флаги должны быть степенями двойки.
Работать с вашим набором можно, но флаги придётся складывать через +, а проверять своей функцией, наподобие такой:
function flags($value) {
    if (!in_array($value, [0, 1, 2, 3, 6, 7, 8, 9])) {
        return false;
    }
    $result = [];
    if (in_array($value, [1, 3, 7, 9])) {
        $result[] = 'a';
    }
    if (in_array($value, [2, 3, 8, 9])) {
        $result[] = 'b';
    }
    if (in_array($value, [6, 7, 8, 9])) {
        $result[] = 'c';
    }
    return $result;
}
Корректность битовой маски обычно не проверяется, потому что обычно нет нормальных критериев. По сути каждый флаг - это степень двойки (или отдельный "бит"). Таким образом, правильная маска - это просто число от 0 до максимально возможного, когда все флаги включены. В этом диапазоне обычно нет дырок. Для понятности попробуйте записывать маску в двоичном формате.

Предположим, у вас есть пять "флагов": a=1, b=2, c=4, d=8, e=16,
тогда значение маски будет от 0 до 31 (т.е. макс. 11111). По выходу за диапазон можно сказать, что она некорректна. Но если у вас 32 флага в маске типа uint, то выход за диапазон не возможен в принципе, и любая маска будет корректной.

Предположим, у вас теперь 4 флага: a=1, b=2, d=8, e=16,
то есть не хватает c=4. Тогда это как бы дырка в маске.
Проверяем этот бит: (mask & 4 == 4)
По идее, если этот бит установлен, то маска некорректна. Но с другой стороны, целевой алгоритм может просто игнорировать бит, который не используется. Так что лишние биты не делают маску некорректной.

Ну и, наконец, возможен уже реальный критерий, когда логика флагов такова, что не все комбинации возможны. Хотя такие кейсы лучше вообще не флагами решать, тем не менее бывает. Например, запрещено устанавливать одновременно b=2 и e=16, тогда условие некорректности будет следующее: 
(mask & 2 > 0) && (mask & 16 > 0)
Либо короче:
(mask & (b | e) > 0)
(mask & 18 > 0)

Аналогично проверяется любое другое условие, накладываемое на маску. Например, если количество включённых флагов лимитировано, то просто считаем количество бит в маске.

P.S. И да, c=6 это некорректный флаг, потому что содержит b=2, и вы никак не определите, является ли mask=c или же mask=b|c.