Skip to content

Commit f92a2c9

Browse files
committed
Rule 7.0.2: Extend test case, support member function pointers
1 parent 62d5dcc commit f92a2c9

File tree

3 files changed

+105
-17
lines changed

3 files changed

+105
-17
lines changed

cpp/misra/src/rules/RULE-7-0-2/NoImplicitBoolConversion.ql

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,12 @@ predicate isBitFieldOfSizeOne(Expr expr) {
4141
)
4242
}
4343

44+
predicate isPointerType(Type t) {
45+
t.getUnspecifiedType() instanceof PointerType or
46+
t.getUnspecifiedType() instanceof ArrayType or
47+
t.getUnspecifiedType() instanceof PointerToMemberType
48+
}
49+
4450
from Element e, string reason
4551
where
4652
not isExcluded(e, ConversionsPackage::noImplicitBoolConversionQuery()) and
@@ -52,7 +58,7 @@ where
5258
not conv.getExpr().getType().getUnspecifiedType() instanceof BoolType and
5359
// Exception 2: Contextual conversion from pointer
5460
not (
55-
conv.getExpr().getType().getUnspecifiedType() instanceof PointerType and
61+
isPointerType(conv.getExpr().getType()) and
5662
isInContextualBoolContext(conv.getExpr())
5763
) and
5864
// Exception 3: Bit-field of size 1
Lines changed: 28 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,28 @@
1-
| test.cpp:46:20:46:28 | (bool)... | Conversion from 'int' to 'bool'. |
2-
| test.cpp:50:7:50:7 | (bool)... | Conversion from 'int' to 'bool'. |
3-
| test.cpp:52:7:52:8 | (bool)... | Conversion from 'uint8_t' to 'bool'. |
4-
| test.cpp:54:8:54:8 | (bool)... | Conversion from 'int' to 'bool'. |
5-
| test.cpp:58:7:58:8 | (bool)... | Conversion from 'uint8_t' to 'bool'. |
6-
| test.cpp:69:8:69:9 | (bool)... | Conversion from 'int16_t' to 'bool'. |
7-
| test.cpp:78:20:78:21 | (bool)... | Conversion from 'int32_t' to 'bool'. |
8-
| test.cpp:84:31:84:32 | (bool)... | Conversion from 'int32_t' to 'bool'. |
9-
| test.cpp:92:30:92:31 | (bool)... | Conversion from 'int32_t' to 'bool'. |
10-
| test.cpp:103:13:103:16 | (bool)... | Conversion from 'int32_t *' to 'bool'. |
11-
| test.cpp:108:13:108:32 | static_cast<bool>... | Conversion from 'int' to 'bool'. |
12-
| test.cpp:109:13:109:14 | (bool)... | Conversion from 'uint8_t' to 'bool'. |
13-
| test.cpp:121:13:121:13 | call to operator bool | Conversion operator call from 'TestClassImplicit' to 'bool'. |
14-
| test.cpp:134:13:134:14 | (bool)... | Conversion from 'Color' to 'bool'. |
15-
| test.cpp:135:7:135:8 | (bool)... | Conversion from 'Color' to 'bool'. |
1+
| test.cpp:53:20:53:28 | (bool)... | Conversion from 'int' to 'bool'. |
2+
| test.cpp:57:7:57:7 | (bool)... | Conversion from 'int' to 'bool'. |
3+
| test.cpp:59:7:59:8 | (bool)... | Conversion from 'uint8_t' to 'bool'. |
4+
| test.cpp:61:8:61:8 | (bool)... | Conversion from 'int' to 'bool'. |
5+
| test.cpp:65:7:65:8 | (bool)... | Conversion from 'uint8_t' to 'bool'. |
6+
| test.cpp:76:8:76:9 | (bool)... | Conversion from 'int16_t' to 'bool'. |
7+
| test.cpp:85:20:85:21 | (bool)... | Conversion from 'int32_t' to 'bool'. |
8+
| test.cpp:91:31:91:32 | (bool)... | Conversion from 'int32_t' to 'bool'. |
9+
| test.cpp:99:30:99:31 | (bool)... | Conversion from 'int32_t' to 'bool'. |
10+
| test.cpp:112:12:112:13 | (bool)... | Conversion from 'int32_t' to 'bool'. |
11+
| test.cpp:127:13:127:16 | (bool)... | Conversion from 'int32_t *' to 'bool'. |
12+
| test.cpp:130:7:130:13 | (bool)... | Conversion from 'decltype(nullptr)' to 'bool'. |
13+
| test.cpp:135:13:135:32 | static_cast<bool>... | Conversion from 'int' to 'bool'. |
14+
| test.cpp:136:13:136:14 | (bool)... | Conversion from 'uint8_t' to 'bool'. |
15+
| test.cpp:148:13:148:13 | call to operator bool | Conversion operator call from 'TestClassImplicit' to 'bool'. |
16+
| test.cpp:161:13:161:14 | (bool)... | Conversion from 'Color' to 'bool'. |
17+
| test.cpp:162:7:162:8 | (bool)... | Conversion from 'Color' to 'bool'. |
18+
| test.cpp:179:13:179:14 | (bool)... | Conversion from 'float' to 'bool'. |
19+
| test.cpp:180:13:180:14 | (bool)... | Conversion from 'double' to 'bool'. |
20+
| test.cpp:181:13:181:14 | (bool)... | Conversion from 'long double' to 'bool'. |
21+
| test.cpp:182:7:182:8 | (bool)... | Conversion from 'float' to 'bool'. |
22+
| test.cpp:184:7:184:8 | (bool)... | Conversion from 'double' to 'bool'. |
23+
| test.cpp:186:7:186:8 | (bool)... | Conversion from 'long double' to 'bool'. |
24+
| test.cpp:195:7:195:8 | (bool)... | Conversion from 'int32_t *' to 'bool'. |
25+
| test.cpp:197:7:197:8 | (bool)... | Conversion from 'int32_t *' to 'bool'. |
26+
| test.cpp:199:13:199:14 | (bool)... | Conversion from 'int32_t *' to 'bool'. |
27+
| test.cpp:211:13:211:14 | (bool)... | Conversion from '..:: *' to 'bool'. |
28+
| test.cpp:212:13:212:14 | (bool)... | Conversion from '..:: *' to 'bool'. |

cpp/misra/test/rules/RULE-7-0-2/test.cpp

Lines changed: 70 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ std::uint8_t g4 = 20;
99
std::int16_t g5 = 100;
1010
std::int32_t g6 = 200;
1111
bool g7 = true;
12+
std::int32_t g8[5] = {1, 2, 3, 4, 5};
1213

1314
// Function declarations
1415
std::int32_t f1();
@@ -30,6 +31,12 @@ class TestClassImplicit {
3031
operator bool() const { return m1 < 0; } // Implicit conversion
3132
};
3233

34+
// Class with member function pointer
35+
class TestClassMemberFunc {
36+
public:
37+
void memberFunc() {}
38+
};
39+
3340
// Bit-field struct for exception #3
3441
struct BitFieldStruct {
3542
unsigned int m1 : 1;
@@ -96,12 +103,32 @@ void test_while_loops() {
96103
}
97104
}
98105

106+
void test_do_while_loops() {
107+
std::int32_t l1 = 5;
108+
bool l2 = true;
109+
110+
do {
111+
--l1;
112+
} while (l1); // NON_COMPLIANT
113+
114+
do {
115+
--l1;
116+
} while (l2); // COMPLIANT
117+
118+
do {
119+
--l1;
120+
} while (l1 > 0); // COMPLIANT
121+
}
122+
99123
void test_pointer_conversions() {
100124
if (f3()) { // COMPLIANT - exception #2
101125
}
102126

103127
bool l1 = f3(); // NON_COMPLIANT
104128
bool l2 = f3() != nullptr; // COMPLIANT
129+
130+
if (nullptr) { // NON_COMPLIANT
131+
}
105132
}
106133

107134
void test_assignment_to_bool() {
@@ -111,7 +138,7 @@ void test_assignment_to_bool() {
111138
bool l4 = g7; // COMPLIANT
112139
}
113140

114-
void test_class_with_explicit_bool_operator() {
141+
void test_classes_with_bool_operators() {
115142
TestClassExplicit l1;
116143

117144
bool l2 = static_cast<bool>(l1); // COMPLIANT - exception #1
@@ -142,4 +169,46 @@ void test_scoped_enum_conversion() {
142169
Status l1 = Status::ACTIVE;
143170

144171
bool l2 = (l1 == Status::ACTIVE); // COMPLIANT
172+
}
173+
174+
void test_floating_point_conversion() {
175+
float l1 = 3.14f;
176+
double l2 = 2.71;
177+
long double l3 = 1.41L;
178+
179+
bool l4 = l1; // NON_COMPLIANT
180+
bool l5 = l2; // NON_COMPLIANT
181+
bool l6 = l3; // NON_COMPLIANT
182+
if (l1) { // NON_COMPLIANT
183+
}
184+
if (l2) { // NON_COMPLIANT
185+
}
186+
if (l3) { // NON_COMPLIANT
187+
}
188+
bool l7 = (l1 > 0.0f); // COMPLIANT
189+
bool l8 = (l2 != 0.0); // COMPLIANT
190+
}
191+
192+
void test_array_conversion() {
193+
std::int32_t l1[5] = {1, 2, 3, 4, 5};
194+
195+
if (l1) { // NON_COMPLIANT
196+
}
197+
if (g8) { // NON_COMPLIANT
198+
}
199+
bool l2 = l1; // NON_COMPLIANT
200+
bool l3 = (l1 != nullptr); // COMPLIANT
201+
}
202+
203+
void test_member_function_pointer_conversion() {
204+
void (TestClassMemberFunc::*l1)() = &TestClassMemberFunc::memberFunc;
205+
void (TestClassMemberFunc::*l2)() = nullptr;
206+
207+
if (l1) { // COMPLIANT - exception #2
208+
}
209+
if (l2) { // COMPLIANT - exception #2
210+
}
211+
bool l3 = l1; // NON_COMPLIANT
212+
bool l4 = l2; // NON_COMPLIANT
213+
bool l5 = (l1 != nullptr); // COMPLIANT
145214
}

0 commit comments

Comments
 (0)