Skip to content

Commit 6e6c79b

Browse files
save work
1 parent 9e73400 commit 6e6c79b

12 files changed

+464
-2
lines changed
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
/**
2+
* @id c/misra/invalid-integer-constant-macro-argument
3+
* @name RULE-7-5: The argument of an integer constant macro shall have an appropriate form
4+
* @description Integer constant macros should be given appropriate values for the size of the
5+
* integer type.
6+
* @kind problem
7+
* @precision very-high
8+
* @problem.severity error
9+
* @tags external/misra/id/rule-7-5
10+
* correctness
11+
* external/misra/obligation/required
12+
*/
13+
14+
import cpp
15+
import codingstandards.c.misra
16+
import codingstandards.cpp.IntegerConstantMacro
17+
import codingstandards.cpp.Cpp14Literal
18+
import semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis
19+
20+
abstract class PossiblyNegativeLiteral extends Expr {
21+
abstract Cpp14Literal::IntegerLiteral getBaseLiteral();
22+
23+
predicate isNegative() {
24+
this instanceof NegativeLiteral
25+
}
26+
}
27+
28+
class NegativeLiteral extends PossiblyNegativeLiteral, UnaryMinusExpr {
29+
Cpp14Literal::IntegerLiteral literal;
30+
31+
NegativeLiteral() {
32+
literal = getOperand()
33+
}
34+
35+
override Cpp14Literal::IntegerLiteral getBaseLiteral() {
36+
result = literal
37+
}
38+
}
39+
40+
class PositiveLiteral extends PossiblyNegativeLiteral, Cpp14Literal::IntegerLiteral {
41+
PositiveLiteral() {
42+
not exists(UnaryMinusExpr l | l.getOperand() = this)
43+
}
44+
45+
override Cpp14Literal::IntegerLiteral getBaseLiteral() {
46+
result = this
47+
}
48+
}
49+
50+
predicate validExpr(Expr expr) {
51+
expr instanceof PossiblyNegativeLiteral
52+
}
53+
54+
predicate usesSuffix(MacroInvocation invoke) {
55+
invoke.getUnexpandedArgument(0).regexpMatch(".*[uUlL]")
56+
}
57+
58+
predicate matchedSign(IntegerConstantMacro macro, PossiblyNegativeLiteral literal) {
59+
literal.isNegative() implies macro.isSigned()
60+
}
61+
62+
predicate validLiteralType(PossiblyNegativeLiteral expr) {
63+
expr.getBaseLiteral() instanceof Cpp14Literal::DecimalLiteral or
64+
expr.getBaseLiteral() instanceof Cpp14Literal::OctalLiteral or
65+
expr.getBaseLiteral() instanceof Cpp14Literal::HexLiteral
66+
}
67+
68+
predicate matchesSize(IntegerConstantMacro macro, PossiblyNegativeLiteral literal) {
69+
// Note: upperBound should equal lowerBound.
70+
upperBound(literal) <= macro.maxValue() and
71+
lowerBound(literal) >= macro.minValue() and exists("123".toBigInt())
72+
}
73+
74+
from MacroInvocation invoke, IntegerConstantMacro macro, string explanation
75+
where
76+
not isExcluded(invoke, Types2Package::invalidIntegerConstantMacroArgumentQuery()) and
77+
invoke.getMacro() = macro and
78+
(
79+
(not validExpr(invoke.getExpr()) and explanation = "invalid expression") or
80+
(validLiteralType(invoke.getExpr()) and explanation = "invalid literal type" + invoke.getExpr().getAQlClass()) or
81+
(usesSuffix(invoke) and explanation = "literal suffixes not allowed") or
82+
(not matchedSign(macro, invoke.getExpr()) and explanation = "signed/unsigned mismatch") or
83+
(not matchesSize(macro, invoke.getExpr()) and explanation = "invalid size")
84+
)
85+
86+
select invoke.getExpr(), "Invalid integer constant macro: " + explanation
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/**
2+
* @id c/misra/use-of-banned-small-integer-constant-macro
3+
* @name RULE-7-6: The small integer variants of the minimum-width integer constant macros shall not be used
4+
* @description Small integer constant macros expression are promoted to type int, which can lead to
5+
* unexpected results.
6+
* @kind problem
7+
* @precision very-high
8+
* @problem.severity warning
9+
* @tags external/misra/id/rule-7-6
10+
* readability
11+
* external/misra/obligation/required
12+
*/
13+
14+
import cpp
15+
import codingstandards.c.misra
16+
import codingstandards.cpp.IntegerConstantMacro
17+
18+
19+
from MacroInvocation macroInvoke, IntegerConstantMacro macro
20+
where
21+
not isExcluded(macroInvoke, Types2Package::useOfBannedSmallIntegerConstantMacroQuery()) and
22+
macroInvoke.getMacro() = macro
23+
and macro.isSmall()
24+
select
25+
macroInvoke, "Usage of small integer constant macro " + macro.getName() + " is not allowed."
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
| test.c:12:13:12:15 | 1.0 | Invalid integer constant macro: invalid literal type |
2+
| test.c:13:13:12:15 | 0b111 | Invalid integer constant macro: invalid literal type |
3+
| test.c:16:13:16:14 | 1 | Invalid integer constant macro: literal suffixes not allowed |
4+
| test.c:17:13:17:14 | 2 | Invalid integer constant macro: literal suffixes not allowed |
5+
| test.c:18:13:18:14 | 3 | Invalid integer constant macro: literal suffixes not allowed |
6+
| test.c:19:13:19:14 | 4 | Invalid integer constant macro: literal suffixes not allowed |
7+
| test.c:20:13:20:15 | 5 | Invalid integer constant macro: literal suffixes not allowed |
8+
| test.c:26:13:26:15 | 256 | Invalid integer constant macro: invalid size |
9+
| test.c:27:13:27:16 | 256 | Invalid integer constant macro: invalid size |
10+
| test.c:28:13:28:17 | 256 | Invalid integer constant macro: invalid size |
11+
| test.c:31:13:31:14 | - ... | Invalid integer constant macro: signed/unsigned mismatch |
12+
| test.c:32:13:32:15 | - ... | Invalid integer constant macro: signed/unsigned mismatch |
13+
| test.c:33:13:33:15 | - ... | Invalid integer constant macro: signed/unsigned mismatch |
14+
| test.c:34:13:34:17 | - ... | Invalid integer constant macro: signed/unsigned mismatch |
15+
| test.c:37:13:37:17 | ... + ... | Invalid integer constant macro: invalid expression |
16+
| test.c:38:13:38:18 | access to array | Invalid integer constant macro: invalid expression |
17+
| test.c:39:13:39:18 | access to array | Invalid integer constant macro: invalid expression |
18+
| test.c:40:13:39:18 | UINT8_MAX | Invalid integer constant macro: invalid expression |
19+
| test.c:54:12:54:15 | 191 | Invalid integer constant macro: invalid size |
20+
| test.c:55:12:55:14 | 255 | Invalid integer constant macro: invalid size |
21+
| test.c:56:12:56:15 | 192 | Invalid integer constant macro: invalid size |
22+
| test.c:57:12:57:15 | 128 | Invalid integer constant macro: invalid size |
23+
| test.c:61:12:57:15 | -129 | Invalid integer constant macro: invalid size |
24+
| test.c:62:12:57:15 | -129 | Invalid integer constant macro: invalid size |
25+
| test.c:63:12:57:15 | -201 | Invalid integer constant macro: invalid size |
26+
| test.c:64:12:57:15 | -0x81 | Invalid integer constant macro: invalid size |
27+
| test.c:76:14:76:18 | 65536 | Invalid integer constant macro: invalid size |
28+
| test.c:78:14:78:20 | 65536 | Invalid integer constant macro: invalid size |
29+
| test.c:91:13:91:17 | 32768 | Invalid integer constant macro: invalid size |
30+
| test.c:93:13:93:18 | 32768 | Invalid integer constant macro: invalid size |
31+
| test.c:97:13:93:18 | -32769 | Invalid integer constant macro: invalid size |
32+
| test.c:98:13:93:18 | -040001 | Invalid integer constant macro: invalid size |
33+
| test.c:99:13:93:18 | -0x8001 | Invalid integer constant macro: invalid size |
34+
| test.c:109:14:109:24 | 4294967296 | Invalid integer constant macro: invalid size |
35+
| test.c:110:14:110:25 | 4294967296 | Invalid integer constant macro: invalid size |
36+
| test.c:120:13:120:22 | 2147483648 | Invalid integer constant macro: invalid size |
37+
| test.c:121:13:121:23 | 34359738368 | Invalid integer constant macro: invalid size |
38+
| test.c:130:14:130:15 | 0 | Invalid integer constant macro: invalid size |
39+
| test.c:133:14:133:34 | 18446744073709551615 | Invalid integer constant macro: invalid size |
40+
| test.c:134:14:134:32 | 18446744073709551615 | Invalid integer constant macro: invalid size |
41+
| test.c:140:13:140:14 | 0 | Invalid integer constant macro: invalid size |
42+
| test.c:143:13:143:32 | 9223372036854775807 | Invalid integer constant macro: invalid size |
43+
| test.c:147:13:147:33 | - ... | Invalid integer constant macro: invalid size |
44+
| test.c:148:13:148:37 | ... - ... | Invalid integer constant macro: invalid expression |
45+
| test.c:148:13:148:37 | ... - ... | Invalid integer constant macro: invalid literal type |
46+
| test.c:148:13:148:37 | ... - ... | Invalid integer constant macro: invalid size |
47+
| test.c:148:13:148:37 | ... - ... | Invalid integer constant macro: signed/unsigned mismatch |
48+
| test.c:150:13:150:37 | ... - ... | Invalid integer constant macro: invalid expression |
49+
| test.c:150:13:150:37 | ... - ... | Invalid integer constant macro: invalid literal type |
50+
| test.c:150:13:150:37 | ... - ... | Invalid integer constant macro: invalid size |
51+
| test.c:150:13:150:37 | ... - ... | Invalid integer constant macro: signed/unsigned mismatch |
52+
| test.c:152:13:152:31 | 9223372036854775807 | Invalid integer constant macro: invalid size |
53+
| test.c:153:13:153:31 | 9223372036854775808 | Invalid integer constant macro: invalid size |
54+
| test.c:154:13:154:31 | - ... | Invalid integer constant macro: invalid size |
55+
| test.c:155:13:155:30 | - ... | Invalid integer constant macro: invalid size |
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
rules/RULE-7-5/InvalidIntegerConstantMacroArgument.ql

c/misra/test/rules/RULE-7-5/test.c

Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
#include "stdint.h"
2+
3+
uint_least8_t g1[] = {
4+
// Basic valid
5+
UINT8_C(0), // COMPLIANT
6+
UINT8_C(1), // COMPLIANT
7+
UINT8_C(8), // COMPLIANT
8+
UINT8_C(0x23), // COMPLIANT
9+
UINT8_C(034), // COMPLIANT
10+
11+
// Incorrect literal types
12+
UINT8_C(1.0), // NON-COMPLIANT
13+
UINT8_C(0b111), // NON-COMPLIANT
14+
15+
// Suffixes disallowed
16+
UINT8_C(1u), // NON-COMPLIANT
17+
UINT8_C(2U), // NON-COMPLIANT
18+
UINT8_C(3l), // NON-COMPLIANT
19+
UINT8_C(4L), // NON-COMPLIANT
20+
UINT8_C(5ul), // NON-COMPLIANT
21+
22+
// Range tests
23+
UINT8_C(255), // COMPLIANT
24+
UINT8_C(0xFF), // COMPLIANT
25+
UINT8_C(0377), // COMPLIANT
26+
UINT8_C(256), // NON-COMPLIANT
27+
UINT8_C(0400), // NON-COMPLIANT
28+
UINT8_C(0x100), // NON-COMPLIANT
29+
30+
// Signage tests
31+
UINT8_C(-1), // NON-COMPLIANT
32+
UINT8_C(-20), // NON-COMPLIANT
33+
UINT8_C(-33), // NON-COMPLIANT
34+
UINT8_C(-0x44), // NON-COMPLIANT
35+
36+
// Invalid nonliteral expressions
37+
UINT8_C(0 + 0), // NON-COMPLIANT
38+
UINT8_C("a"[0]), // NON-COMPLIANT
39+
UINT8_C(0["a"]), // NON-COMPLIANT
40+
UINT8_C(UINT8_MAX), // NON-COMPLIANT
41+
};
42+
43+
int_least8_t g2[] = {
44+
// Basic valid
45+
INT8_C(0), // COMPLIANT
46+
INT8_C(1), // COMPLIANT
47+
INT8_C(8), // COMPLIANT
48+
INT8_C(0x23), // COMPLIANT
49+
INT8_C(034), // COMPLIANT
50+
51+
// Range tests
52+
INT8_C(127), // COMPLIANT
53+
INT8_C(0x79), // COMPLIANT
54+
INT8_C(0177), // COMPLIANT
55+
INT8_C(128), // NON-COMPLIANT
56+
INT8_C(0200), // NON-COMPLIANT
57+
INT8_C(0x80), // NON-COMPLIANT
58+
INT8_C(-128), // COMPLIANT
59+
INT8_C(-0x80), // COMPLIANT
60+
INT8_C(-0200), // COMPLIANT
61+
INT8_C(-129), // NON-COMPLIANT
62+
INT8_C(-0201), // NON-COMPLIANT
63+
INT8_C(-0x81), // NON-COMPLIANT
64+
};
65+
66+
uint_least16_t g3[] = {
67+
// Basic valid
68+
UINT16_C(0), // COMPLIANT
69+
UINT16_C(0x23), // COMPLIANT
70+
UINT16_C(034), // COMPLIANT
71+
72+
// Range tests
73+
UINT16_C(65535), // COMPLIANT
74+
UINT16_C(0xFFFF), // COMPLIANT
75+
UINT16_C(0177777), // COMPLIANT
76+
UINT16_C(65536), // NON-COMPLIANT
77+
UINT16_C(0200000), // NON-COMPLIANT
78+
UINT16_C(0x10000), // NON-COMPLIANT
79+
};
80+
81+
int_least16_t g4[] = {
82+
// Basic valid
83+
INT16_C(0), // COMPLIANT
84+
INT16_C(0x23), // COMPLIANT
85+
INT16_C(034), // COMPLIANT
86+
87+
// Range tests
88+
INT16_C(32767), // COMPLIANT
89+
INT16_C(0x7FFF), // COMPLIANT
90+
INT16_C(077777), // COMPLIANT
91+
INT16_C(32768), // NON-COMPLIANT
92+
INT16_C(0100000), // NON-COMPLIANT
93+
INT16_C(0x8000), // NON-COMPLIANT
94+
INT16_C(-32768), // COMPLIANT
95+
INT16_C(-040000), // COMPLIANT
96+
INT16_C(-0x8000), // COMPLIANT
97+
INT16_C(-32769), // NON-COMPLIANT
98+
INT16_C(-040001), // NON-COMPLIANT
99+
INT16_C(-0x8001), // NON-COMPLIANT
100+
};
101+
102+
uint_least32_t g5[] = {
103+
// Basic valid
104+
UINT32_C(0), // COMPLIANT
105+
106+
// Range tests
107+
UINT32_C(4294967295), // COMPLIANT
108+
UINT32_C(0xFFFFFFFF), // COMPLIANT
109+
UINT32_C(4294967296), // NON-COMPLIANT
110+
UINT32_C(0x100000000), // NON-COMPLIANT
111+
};
112+
113+
int_least32_t g6[] = {
114+
// Basic valid
115+
INT32_C(0), // COMPLIANT
116+
117+
// Range tests
118+
INT32_C(2147483647), // COMPLIANT
119+
INT32_C(0x7FFFFFFF), // COMPLIANT
120+
INT32_C(2147483648), // NON-COMPLIANT
121+
INT32_C(0x800000000), // NON-COMPLIANT
122+
INT32_C(-2147483648), // COMPLIANT
123+
INT32_C(-0x80000000), // COMPLIANT
124+
INT32_C(-2147483647), // NON-COMPLIANT
125+
INT32_C(-0x800000001), // NON-COMPLIANT
126+
};
127+
128+
uint_least64_t g7[] = {
129+
// Basic valid
130+
UINT64_C(0), // COMPLIANT
131+
132+
// Range tests
133+
UINT64_C(18446744073709551615), // COMPLIANT
134+
UINT64_C(0xFFFFFFFFFFFFFFFF), // COMPLIANT
135+
// Compile time error if we try to create integer literals beyond this.
136+
};
137+
138+
int_least64_t g8[] = {
139+
// Basic valid
140+
INT64_C(0), // COMPLIANT
141+
142+
// Range tests
143+
INT64_C(9223372036854775807), // COMPLIANT
144+
// INT64_C(9223372036854775808) is a compile-time error
145+
146+
// -9223372036854775808 allowed, but cannot be created via unary- without compile time errors.
147+
INT64_C(-9223372036854775807), // COMPLIANT
148+
INT64_C(-9223372036854775807 - 1), // COMPLIANT
149+
// -9223372036854775809 is not allowed, and cannot be created via unary- without compile time errors.
150+
INT64_C(-9223372036854775807 - 2), // NON-COMPLIANT
151+
152+
INT64_C(0x7FFFFFFFFFFFFFFF), // COMPLIANT
153+
INT64_C(0x8000000000000000), // NON-COMPLIANT
154+
INT64_C(-0x8000000000000000), // COMPLIANT
155+
INT64_C(-0x8000000000000001), // NON-COMPLIANT
156+
};
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
| test.c:3:13:3:24 | INT8_C(c) | Usage of small integer constant macro INT8_C is not allowed. |
2+
| test.c:4:14:4:26 | UINT8_C(c) | Usage of small integer constant macro UINT8_C is not allowed. |
3+
| test.c:5:14:5:28 | INT16_C(c) | Usage of small integer constant macro INT16_C is not allowed. |
4+
| test.c:6:15:6:30 | UINT16_C(c) | Usage of small integer constant macro UINT16_C is not allowed. |
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
rules/RULE-7-6/UseOfBannedSmallIntegerConstantMacro.ql

c/misra/test/rules/RULE-7-6/test.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#include "stdint.h"
2+
3+
int8_t g1 = INT8_C(0x12); // NON-COMPLIANT
4+
uint8_t g2 = UINT8_C(0x12); // NON-COMPLIANT
5+
int16_t g3 = INT16_C(0x1234); // NON-COMPLIANT
6+
uint16_t g4 = UINT16_C(0x1234); // NON-COMPLIANT
7+
int32_t g5 = INT32_C(0x1234); // COMPLIANT
8+
uint32_t g6 = UINT32_C(0x1234); // COMPLIANT
9+
int64_t g7 = INT64_C(0x1234); // COMPLIANT
10+
uint64_t g8 = UINT64_C(0x1234); // COMPLIANT
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import cpp
2+
3+
class IntegerConstantMacro extends Macro {
4+
boolean signed;
5+
int size;
6+
IntegerConstantMacro() {
7+
(
8+
signed = true and size = getName().regexpCapture("INT(8|16|32|64)_C", 1).toInt()
9+
) or (
10+
signed = false and size = getName().regexpCapture("UINT(8|16|32|64)_C", 1).toInt()
11+
)
12+
}
13+
14+
predicate isSmall() {
15+
size < 32
16+
}
17+
18+
int getSize() {
19+
result = size
20+
}
21+
22+
predicate isSigned() {
23+
signed = true
24+
}
25+
26+
int maxValue() {
27+
(signed = true and result = 2.pow(getSize() - 1) - 1) or
28+
(signed = false and result = 2.pow(getSize()) - 1)
29+
}
30+
31+
int minValue() {
32+
(signed = true and result = -(2.0.pow(getSize() - 1))) or
33+
(signed = false and result = 0)
34+
}
35+
}

0 commit comments

Comments
 (0)