Skip to content

Commit c8e0ade

Browse files
Reject char literals, add false negatives for macros.
1 parent 0cd626b commit c8e0ade

8 files changed

+88
-57
lines changed

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

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
* @name RULE-7-5: The argument of an integer constant macro shall not use literal suffixes u, l, or ul
44
* @description Integer constant macros should be used integer literal values with no u/l suffix.
55
* @kind problem
6-
* @precision very-high
7-
* @problem.severity error
6+
* @precision high
7+
* @problem.severity warning
88
* @tags external/misra/id/rule-7-5
99
* readability
1010
* maintainability
@@ -17,7 +17,10 @@ import codingstandards.cpp.IntegerConstantMacro
1717
import codingstandards.cpp.Literals
1818

1919
string argumentSuffix(MacroInvocation invoke) {
20-
result = invoke.getUnexpandedArgument(0).regexpCapture(".*[^uUlL]([uUlL]+)$", 1)
20+
// Compiler strips the suffix unless we look at the unexpanded argument text.
21+
// Unexpanded argument text can be malformed in all sorts of ways, so make
22+
// this match relatively strict, to be safe.
23+
result = invoke.getUnexpandedArgument(0).regexpCapture("([0-9]+|0[xX][0-9A-F]+)([uUlL]+)$", 2)
2124
}
2225

2326
from MacroInvocation invoke, PossiblyNegativeLiteral argument, string suffix

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* @description Integer constant macros should be given a literal value as an argument.
55
* @kind problem
66
* @precision very-high
7-
* @problem.severity error
7+
* @problem.severity warning
88
* @tags external/misra/id/rule-7-5
99
* correctness
1010
* external/misra/obligation/required

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

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -34,19 +34,30 @@ predicate validLiteralType(PossiblyNegativeLiteral literal) {
3434
* Detect this pattern before macro expansion.
3535
*/
3636
predicate seemsBinaryLiteral(MacroInvocation invoke) {
37-
invoke.getUnexpandedArgument(0).regexpMatch("0[bB][01]+")
37+
invoke.getUnexpandedArgument(0).regexpMatch("-?0[bB][01]+")
38+
}
39+
40+
/**
41+
* Extractor converts `xINTsize_C('a')` to a decimal literal. Therefore, detect
42+
* this pattern before macro expansion.
43+
*/
44+
predicate seemsCharLiteral(MacroInvocation invoke) {
45+
invoke.getUnexpandedArgument(0).regexpMatch("-?'\\\\?.'")
3846
}
3947

4048
string explainIncorrectArgument(MacroInvocation invoke) {
4149
if seemsBinaryLiteral(invoke)
4250
then result = "binary literal"
4351
else
44-
exists(PossiblyNegativeLiteral literal |
45-
literal = invoke.getExpr() and
46-
if literal.getBaseLiteral() instanceof Cpp14Literal::FloatingLiteral
47-
then result = "floating point literal"
48-
else result = "invalid literal"
49-
)
52+
if seemsCharLiteral(invoke)
53+
then result = "char literal"
54+
else
55+
exists(PossiblyNegativeLiteral literal |
56+
literal = invoke.getExpr() and
57+
if literal.getBaseLiteral() instanceof Cpp14Literal::FloatingLiteral
58+
then result = "floating point literal"
59+
else result = "invalid literal"
60+
)
5061
}
5162

5263
from MacroInvocation invoke, PossiblyNegativeLiteral literal
@@ -56,7 +67,8 @@ where
5667
literal = invoke.getExpr() and
5768
(
5869
not validLiteralType(literal) or
59-
seemsBinaryLiteral(invoke)
70+
seemsBinaryLiteral(invoke) or
71+
seemsCharLiteral(invoke)
6072
)
6173
select literal,
6274
"Integer constant macro " + invoke.getMacroName() + " used with " +
Lines changed: 31 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,31 @@
1-
| test.c:13:13:13:16 | - ... | Value provided to integer constant macro UINT8_C cannot be negative |
2-
| test.c:15:13:15:18 | - ... | Value provided to integer constant macro UINT8_C cannot be negative |
3-
| test.c:30:13:30:15 | 256 | Value provided to integer constant macro UINT8_C is outside of the allowed range 0..255 |
4-
| test.c:31:13:31:16 | 256 | Value provided to integer constant macro UINT8_C is outside of the allowed range 0..255 |
5-
| test.c:32:13:32:17 | 256 | Value provided to integer constant macro UINT8_C is outside of the allowed range 0..255 |
6-
| test.c:35:13:35:14 | - ... | Value provided to integer constant macro UINT8_C cannot be negative |
7-
| test.c:36:13:36:15 | - ... | Value provided to integer constant macro UINT8_C cannot be negative |
8-
| test.c:37:13:37:15 | - ... | Value provided to integer constant macro UINT8_C cannot be negative |
9-
| test.c:38:13:38:17 | - ... | Value provided to integer constant macro UINT8_C cannot be negative |
10-
| test.c:59:12:59:14 | 128 | Value provided to integer constant macro INT8_C is outside of the allowed range -128..127 |
11-
| test.c:60:12:60:15 | 128 | Value provided to integer constant macro INT8_C is outside of the allowed range -128..127 |
12-
| test.c:61:12:61:15 | 128 | Value provided to integer constant macro INT8_C is outside of the allowed range -128..127 |
13-
| test.c:65:12:65:15 | - ... | Value provided to integer constant macro INT8_C is outside of the allowed range -128..127 |
14-
| test.c:66:12:66:16 | - ... | Value provided to integer constant macro INT8_C is outside of the allowed range -128..127 |
15-
| test.c:67:12:67:16 | - ... | Value provided to integer constant macro INT8_C is outside of the allowed range -128..127 |
16-
| test.c:80:14:80:18 | 65536 | Value provided to integer constant macro UINT16_C is outside of the allowed range 0..65535 |
17-
| test.c:81:14:81:20 | 65536 | Value provided to integer constant macro UINT16_C is outside of the allowed range 0..65535 |
18-
| test.c:82:14:82:20 | 65536 | Value provided to integer constant macro UINT16_C is outside of the allowed range 0..65535 |
19-
| test.c:95:13:95:17 | 32768 | Value provided to integer constant macro INT16_C is outside of the allowed range -32768..32767 |
20-
| test.c:96:13:96:19 | 32768 | Value provided to integer constant macro INT16_C is outside of the allowed range -32768..32767 |
21-
| test.c:97:13:97:18 | 32768 | Value provided to integer constant macro INT16_C is outside of the allowed range -32768..32767 |
22-
| test.c:101:13:101:18 | - ... | Value provided to integer constant macro INT16_C is outside of the allowed range -32768..32767 |
23-
| test.c:102:13:102:20 | - ... | Value provided to integer constant macro INT16_C is outside of the allowed range -32768..32767 |
24-
| test.c:103:13:103:19 | - ... | Value provided to integer constant macro INT16_C is outside of the allowed range -32768..32767 |
25-
| test.c:113:14:113:24 | 4294967296 | Value provided to integer constant macro UINT32_C is outside of the allowed range 0..4294967295 |
26-
| test.c:114:14:114:25 | 4294967296 | Value provided to integer constant macro UINT32_C is outside of the allowed range 0..4294967295 |
27-
| test.c:124:13:124:22 | 2147483648 | Value provided to integer constant macro INT32_C is outside of the allowed range -2147483648..2147483647 |
28-
| test.c:125:13:125:22 | 2147483648 | Value provided to integer constant macro INT32_C is outside of the allowed range -2147483648..2147483647 |
29-
| test.c:128:13:128:23 | - ... | Value provided to integer constant macro INT32_C is outside of the allowed range -2147483648..2147483647 |
30-
| test.c:129:13:129:23 | - ... | Value provided to integer constant macro INT32_C is outside of the allowed range -2147483648..2147483647 |
1+
| test.c:17:13:17:16 | - ... | Value provided to integer constant macro UINT8_C cannot be negative |
2+
| test.c:19:13:19:18 | - ... | Value provided to integer constant macro UINT8_C cannot be negative |
3+
| test.c:21:13:21:16 | - ... | Value provided to integer constant macro UINT8_C cannot be negative |
4+
| test.c:37:13:37:15 | 256 | Value provided to integer constant macro UINT8_C is outside of the allowed range 0..255 |
5+
| test.c:38:13:38:16 | 256 | Value provided to integer constant macro UINT8_C is outside of the allowed range 0..255 |
6+
| test.c:39:13:39:17 | 256 | Value provided to integer constant macro UINT8_C is outside of the allowed range 0..255 |
7+
| test.c:42:13:42:14 | - ... | Value provided to integer constant macro UINT8_C cannot be negative |
8+
| test.c:43:13:43:15 | - ... | Value provided to integer constant macro UINT8_C cannot be negative |
9+
| test.c:44:13:44:15 | - ... | Value provided to integer constant macro UINT8_C cannot be negative |
10+
| test.c:45:13:45:17 | - ... | Value provided to integer constant macro UINT8_C cannot be negative |
11+
| test.c:70:12:70:14 | 128 | Value provided to integer constant macro INT8_C is outside of the allowed range -128..127 |
12+
| test.c:71:12:71:15 | 128 | Value provided to integer constant macro INT8_C is outside of the allowed range -128..127 |
13+
| test.c:72:12:72:15 | 128 | Value provided to integer constant macro INT8_C is outside of the allowed range -128..127 |
14+
| test.c:76:12:76:15 | - ... | Value provided to integer constant macro INT8_C is outside of the allowed range -128..127 |
15+
| test.c:77:12:77:16 | - ... | Value provided to integer constant macro INT8_C is outside of the allowed range -128..127 |
16+
| test.c:78:12:78:16 | - ... | Value provided to integer constant macro INT8_C is outside of the allowed range -128..127 |
17+
| test.c:91:14:91:18 | 65536 | Value provided to integer constant macro UINT16_C is outside of the allowed range 0..65535 |
18+
| test.c:92:14:92:20 | 65536 | Value provided to integer constant macro UINT16_C is outside of the allowed range 0..65535 |
19+
| test.c:93:14:93:20 | 65536 | Value provided to integer constant macro UINT16_C is outside of the allowed range 0..65535 |
20+
| test.c:106:13:106:17 | 32768 | Value provided to integer constant macro INT16_C is outside of the allowed range -32768..32767 |
21+
| test.c:107:13:107:19 | 32768 | Value provided to integer constant macro INT16_C is outside of the allowed range -32768..32767 |
22+
| test.c:108:13:108:18 | 32768 | Value provided to integer constant macro INT16_C is outside of the allowed range -32768..32767 |
23+
| test.c:112:13:112:18 | - ... | Value provided to integer constant macro INT16_C is outside of the allowed range -32768..32767 |
24+
| test.c:113:13:113:20 | - ... | Value provided to integer constant macro INT16_C is outside of the allowed range -32768..32767 |
25+
| test.c:114:13:114:19 | - ... | Value provided to integer constant macro INT16_C is outside of the allowed range -32768..32767 |
26+
| test.c:124:14:124:24 | 4294967296 | Value provided to integer constant macro UINT32_C is outside of the allowed range 0..4294967295 |
27+
| test.c:125:14:125:25 | 4294967296 | Value provided to integer constant macro UINT32_C is outside of the allowed range 0..4294967295 |
28+
| test.c:135:13:135:22 | 2147483648 | Value provided to integer constant macro INT32_C is outside of the allowed range -2147483648..2147483647 |
29+
| test.c:136:13:136:22 | 2147483648 | Value provided to integer constant macro INT32_C is outside of the allowed range -2147483648..2147483647 |
30+
| test.c:139:13:139:23 | - ... | Value provided to integer constant macro INT32_C is outside of the allowed range -2147483648..2147483647 |
31+
| test.c:140:13:140:23 | - ... | Value provided to integer constant macro INT32_C is outside of the allowed range -2147483648..2147483647 |
Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
| test.c:18:13:18:14 | 1 | Value suffix 'u' is not allowed on provided argument to integer constant macro UINT8_C. |
2-
| test.c:19:13:19:14 | 2 | Value suffix 'U' is not allowed on provided argument to integer constant macro UINT8_C. |
3-
| test.c:20:13:20:14 | 3 | Value suffix 'l' is not allowed on provided argument to integer constant macro UINT8_C. |
4-
| test.c:21:13:21:14 | 4 | Value suffix 'L' is not allowed on provided argument to integer constant macro UINT8_C. |
5-
| test.c:22:13:22:15 | 5 | Value suffix 'ul' is not allowed on provided argument to integer constant macro UINT8_C. |
6-
| test.c:23:13:23:15 | 5 | Value suffix 'll' is not allowed on provided argument to integer constant macro UINT8_C. |
7-
| test.c:24:13:24:16 | 5 | Value suffix 'ull' is not allowed on provided argument to integer constant macro UINT8_C. |
1+
| test.c:25:13:25:14 | 1 | Value suffix 'u' is not allowed on provided argument to integer constant macro UINT8_C. |
2+
| test.c:26:13:26:14 | 2 | Value suffix 'U' is not allowed on provided argument to integer constant macro UINT8_C. |
3+
| test.c:27:13:27:14 | 3 | Value suffix 'l' is not allowed on provided argument to integer constant macro UINT8_C. |
4+
| test.c:28:13:28:14 | 4 | Value suffix 'L' is not allowed on provided argument to integer constant macro UINT8_C. |
5+
| test.c:29:13:29:15 | 5 | Value suffix 'ul' is not allowed on provided argument to integer constant macro UINT8_C. |
6+
| test.c:30:13:30:15 | 5 | Value suffix 'll' is not allowed on provided argument to integer constant macro UINT8_C. |
7+
| test.c:31:13:31:16 | 5 | Value suffix 'ull' is not allowed on provided argument to integer constant macro UINT8_C. |
Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
| test.c:41:13:41:17 | ... + ... | Argument to integer constant macro UINT8_C must be an integer literal. |
2-
| test.c:42:13:42:18 | access to array | Argument to integer constant macro UINT8_C must be an integer literal. |
3-
| test.c:43:13:43:19 | access to array | Argument to integer constant macro UINT8_C must be an integer literal. |
4-
| test.c:156:13:156:37 | ... - ... | Argument to integer constant macro INT64_C must be an integer literal. |
5-
| test.c:157:13:157:47 | ... - ... | Argument to integer constant macro INT64_C must be an integer literal. |
1+
| test.c:48:13:48:17 | ... + ... | Argument to integer constant macro UINT8_C must be an integer literal. |
2+
| test.c:49:13:49:18 | access to array | Argument to integer constant macro UINT8_C must be an integer literal. |
3+
| 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. |
Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1-
| test.c:12:13:12:15 | 1.0 | Integer constant macro UINT8_C used with floating point literal argument, only decimal, octal, or hex integer literal allowed. |
2-
| test.c:13:13:13:16 | - ... | Integer constant macro UINT8_C used with floating point literal argument, only decimal, octal, or hex integer literal allowed. |
3-
| test.c:14:13:14:17 | 7 | Integer constant macro UINT8_C used with binary literal argument, only decimal, octal, or hex integer literal allowed. |
1+
| test.c:16:13:16:15 | 1.0 | Integer constant macro UINT8_C used with floating point literal argument, only decimal, octal, or hex integer literal allowed. |
2+
| test.c:17:13:17:16 | - ... | Integer constant macro UINT8_C used with floating point literal argument, only decimal, octal, or hex integer literal allowed. |
3+
| test.c:18:13:18:17 | 7 | Integer constant macro UINT8_C used with binary literal argument, only decimal, octal, or hex integer literal allowed. |
4+
| test.c:19:13:19:18 | - ... | Integer constant macro UINT8_C used with binary literal argument, only decimal, octal, or hex integer literal allowed. |
5+
| test.c:20:13:20:15 | 97 | Integer constant macro UINT8_C used with char literal argument, only decimal, octal, or hex integer literal allowed. |
6+
| test.c:21:13:21:16 | - ... | Integer constant macro UINT8_C used with char literal argument, only decimal, octal, or hex integer literal allowed. |
7+
| test.c:22:13:22:16 | 10 | Integer constant macro UINT8_C used with char literal argument, only decimal, octal, or hex integer literal allowed. |

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
1+
#include "stdbool.h"
12
#include "stdint.h"
23

4+
#define NULL 0
5+
#define NULLPTR ((void *)NULL)
6+
37
uint_least8_t g1[] = {
48
// Basic valid
59
UINT8_C(0), // COMPLIANT
@@ -13,6 +17,9 @@ uint_least8_t g1[] = {
1317
UINT8_C(-1.0), // NON-COMPLIANT
1418
UINT8_C(0b111), // NON-COMPLIANT
1519
UINT8_C(-0b111), // NON-COMPLIANT
20+
UINT8_C('a'), // NON-COMPLIANT
21+
UINT8_C(-'$'), // NON-COMPLIANT
22+
UINT8_C('\n'), // NON-COMPLIANT
1623

1724
// Suffixes disallowed
1825
UINT8_C(1u), // NON-COMPLIANT
@@ -42,6 +49,10 @@ uint_least8_t g1[] = {
4249
UINT8_C("a"[0]), // NON-COMPLIANT
4350
UINT8_C(0 ["a"]), // NON-COMPLIANT
4451
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]
4556
};
4657

4758
int_least8_t g2[] = {

0 commit comments

Comments
 (0)