Skip to content

Commit 3708edf

Browse files
Reject macros inside (u)INT<size>_C macros (eg, 1NT8_C(true)) and remove exception
Added exception to handle INT63_MIN as an addition expression, but that exception is actually quite dangerous and should be removed.
1 parent 3012bfa commit 3708edf

File tree

3 files changed

+24
-32
lines changed

3 files changed

+24
-32
lines changed

c/misra/src/rules/RULE-7-5/InvalidIntegerConstantMacroArgument.ql

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -16,27 +16,19 @@ import codingstandards.cpp.IntegerConstantMacro
1616
import codingstandards.cpp.Literals
1717
import semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis
1818

19-
/**
20-
* The max negative 64 bit signed integer is one less than the negative of the
21-
* max positive signed 64 bit integer. The only way to create a "negative"
22-
* literal is to use unary- negation of a positive literal. Therefore, clang
23-
* (and likely other compilers) rejects `INT64_C(-92233...808)` but accepts
24-
* `INT64_C(-92233...807 - 1)`. Therefore, in this case allow non-literal
25-
* expressions.
26-
*/
27-
predicate specialMaxNegative64Exception(IntegerConstantMacro macro, Expr expr) {
28-
macro.getSize() = 64 and
29-
macro.isSigned() and
30-
// Set a cutoff with precision, fix once BigInt library is available.
31-
upperBound(expr) < macro.minValue() * 0.999999999 and
32-
upperBound(expr) > macro.minValue() * 1.000000001
19+
predicate containsMacroInvocation(MacroInvocation outer, MacroInvocation inner) {
20+
outer.getExpr() = inner.getExpr() and
21+
exists(outer.getUnexpandedArgument(0).indexOf(inner.getMacroName()))
3322
}
3423

3524
from MacroInvocation invoke, IntegerConstantMacro macro
3625
where
3726
not isExcluded(invoke, Types2Package::invalidIntegerConstantMacroArgumentQuery()) and
3827
invoke.getMacro() = macro and
39-
not invoke.getExpr() instanceof PossiblyNegativeLiteral and
40-
not specialMaxNegative64Exception(macro, invoke.getExpr())
28+
(
29+
not invoke.getExpr() instanceof PossiblyNegativeLiteral
30+
or
31+
containsMacroInvocation(invoke, _)
32+
)
4133
select invoke.getExpr(),
4234
"Argument to integer constant macro " + macro.getName() + " must be an integer literal."
Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
| test.c:48:13:48:17 | ... + ... | Argument to integer constant macro UINT8_C must be an integer literal. |
22
| test.c:49:13:49:18 | access to array | Argument to integer constant macro UINT8_C must be an integer literal. |
33
| test.c:50:13:50:19 | access to array | Argument to integer constant macro UINT8_C must be an integer literal. |
4-
| test.c:167:13:167:37 | ... - ... | Argument to integer constant macro INT64_C must be an integer literal. |
5-
| test.c:168:13:168:47 | ... - ... | Argument to integer constant macro INT64_C must be an integer literal. |
4+
| test.c:51:5:51:22 | 255 | Argument to integer constant macro UINT8_C must be an integer literal. |
5+
| test.c:52:5:52:17 | 1 | Argument to integer constant macro UINT8_C must be an integer literal. |
6+
| test.c:53:5:53:18 | 0 | Argument to integer constant macro UINT8_C must be an integer literal. |
7+
| test.c:54:5:54:17 | 0 | Argument to integer constant macro UINT8_C must be an integer literal. |
8+
| test.c:55:5:55:20 | 0 | Argument to integer constant macro UINT8_C must be an integer literal. |

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

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -48,11 +48,11 @@ uint_least8_t g1[] = {
4848
UINT8_C(0 + 0), // NON-COMPLIANT
4949
UINT8_C("a"[0]), // NON-COMPLIANT
5050
UINT8_C(0 ["a"]), // NON-COMPLIANT
51-
UINT8_C(UINT8_MAX), // COMPLIANT
52-
UINT8_C(true), // NON-COMPLIANT[False Negative]
53-
UINT8_C(false), // NON-COMPLIANT[False Negative]
54-
UINT8_C(NULL), // NON-COMPLIANT[False Negative]
55-
UINT8_C(NULLPTR), // NON-COMPLIANT[False Negative]
51+
UINT8_C(UINT8_MAX), // NON-COMPLIANT
52+
UINT8_C(true), // NON-COMPLIANT
53+
UINT8_C(false), // NON-COMPLIANT
54+
UINT8_C(NULL), // NON-COMPLIANT
55+
UINT8_C(NULLPTR), // NON-COMPLIANT
5656
};
5757

5858
int_least8_t g2[] = {
@@ -158,20 +158,17 @@ int_least64_t g8[] = {
158158
INT64_C(9223372036854775807), // COMPLIANT
159159
// INT64_C(9223372036854775808) is a compile-time error
160160

161-
// -9223372036854775808 allowed, but cannot be created via unary- without
162-
// compile time errors.
163-
INT64_C(-9223372036854775807), // COMPLIANT
164-
INT64_C(-9223372036854775807 - 1), // COMPLIANT
165-
// -9223372036854775809 is not allowed, and cannot be created via unary-
166-
// without compile time errors.
167-
INT64_C(-9223372036854775807 - 2), // NON-COMPLIANT
168-
INT64_C(-9223372036854775807 - 20000000000), // NON-COMPLIANT
161+
INT64_C(-9223372036854775807), // COMPLIANT
162+
// -9223372036854775808 is correctly sized, but not a valid decimal literal
163+
// value.
164+
// -9223372036854775809 is not correctly sized, and not a valid decimal
165+
// literal value.
169166

170167
INT64_C(0x7FFFFFFFFFFFFFFF), // COMPLIANT
171168
INT64_C(0x8000000000000000), // NON-COMPLIANT[FALSE NEGATIVE]
172169
INT64_C(-0x8000000000000000), // COMPLIANT
173170
INT64_C(-0x8000000000000001), // NON-COMPLIANT[FALSE NEGATIVE]
174-
INT64_C(-0x8001000000000000), // NON-COMPLIANT
171+
INT64_C(-0x8001000000000000), // NON-COMPLIANT[FALSE NEGATIVE]
175172
};
176173

177174
// Other edge cases:

0 commit comments

Comments
 (0)