Skip to content

Commit 0b9c7af

Browse files
committed
Exclude enums that implement the BitmaskType trait
1 parent 9298ce5 commit 0b9c7af

File tree

4 files changed

+34
-6
lines changed

4 files changed

+34
-6
lines changed

cpp/autosar/src/rules/A4-5-1/EnumUsedInArithmeticContexts.ql

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import cpp
2020
import codingstandards.cpp.autosar
2121
import codingstandards.cpp.Operator
22+
import codingstandards.cpp.Type
2223

2324
class AllowedOperatorUse extends OperatorUse {
2425
AllowedOperatorUse() {
@@ -36,5 +37,7 @@ where
3637
access.(EnumConstantAccess).getTarget().getDeclaringEnum() = enum or
3738
access.(VariableAccess).getType() = enum
3839
) and
39-
not operatorUse instanceof AllowedOperatorUse
40+
not operatorUse instanceof AllowedOperatorUse and
41+
// Enums that implement the BitmaskType trait are an exception.
42+
not enum instanceof BitmaskType
4043
select access, "Enum $@ is used as an operand of arithmetic operation.", enum, enum.getName()

cpp/autosar/test/rules/A4-5-1/EnumUsedInArithmeticContexts.expected

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,5 +102,3 @@
102102
| enum_class.cpp:102:3:102:3 | a | Enum $@ is used as an operand of arithmetic operation. | enum_class.cpp:1:12:1:25 | FunctionalLang | FunctionalLang |
103103
| enum_class.cpp:103:3:103:3 | a | Enum $@ is used as an operand of arithmetic operation. | enum_class.cpp:1:12:1:25 | FunctionalLang | FunctionalLang |
104104
| enum_class.cpp:103:6:103:6 | b | Enum $@ is used as an operand of arithmetic operation. | enum_class.cpp:1:12:1:25 | FunctionalLang | FunctionalLang |
105-
| enum_class.cpp:120:3:120:5 | one | Enum $@ is used as an operand of arithmetic operation. | enum_class.cpp:106:12:106:15 | byte | byte |
106-
| enum_class.cpp:120:8:120:10 | two | Enum $@ is used as an operand of arithmetic operation. | enum_class.cpp:106:12:106:15 | byte | byte |

cpp/autosar/test/rules/A4-5-1/enum_class.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -112,9 +112,8 @@ byte operator~(byte lhs) { return lhs; }
112112
byte operator&=(byte lhs, byte rhs) { return lhs; }
113113
byte operator|=(byte lhs, byte rhs) { return lhs; }
114114

115-
void test_bitmasktype_enum_class() { // COMPLIANT[FALSE_POSITIVE] - Type
116-
// implementing the BitmaskType trait
117-
// should be excluded.
115+
void test_bitmasktype_enum_class() { // COMPLIANT - byte implements the
116+
// BitmaskType trait.
118117
byte one, two;
119118

120119
one &two;

cpp/common/src/codingstandards/cpp/Type.qll

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,31 @@ class FundamentalType extends BuiltInType {
2222
class IncompleteType extends Class {
2323
IncompleteType() { not hasDefinition() }
2424
}
25+
26+
/** A type that implements the BitmaskType trait.
27+
* https://en.cppreference.com/w/cpp/named_req/BitmaskType
28+
*
29+
*/
30+
abstract class BitmaskType extends Type { }
31+
32+
/** Holds if `enum` implements required overload `overload` to implement
33+
* the BitmaskType trait.
34+
*/
35+
private predicate isRequiredEnumOverload(Enum enum, Function overload) {
36+
overload.getName().regexpMatch("operator([&|^~]|&=|\\|=)")
37+
and
38+
forex(Parameter p | p = overload.getAParameter() |
39+
(
40+
p.getType() = enum
41+
or
42+
p.getType().(ReferenceType).getBaseType() = enum
43+
)
44+
)
45+
}
46+
47+
private class EnumBitmaskType extends BitmaskType, Enum {
48+
EnumBitmaskType() {
49+
// Implements all the required overload
50+
count(Function overload | isRequiredEnumOverload(this, overload)) = 6
51+
}
52+
}

0 commit comments

Comments
 (0)