Skip to content

Commit 0730c2d

Browse files
authored
Merge pull request #724 from github/michaelrfairhurst/implement-types2-package
Michaelrfairhurst/implement types2 package
2 parents 8c87dba + 47a6600 commit 0730c2d

23 files changed

+749
-7
lines changed
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/**
2+
* @id c/misra/incorrectly-sized-integer-constant-macro-argument
3+
* @name RULE-7-5: The argument of an integer constant macro shall have an appropriate size
4+
* @description Integer constant macros argument values should be values of a compatible size.
5+
* @kind problem
6+
* @precision very-high
7+
* @problem.severity error
8+
* @tags external/misra/id/rule-7-5
9+
* correctness
10+
* external/misra/c/2012/amendment3
11+
* external/misra/obligation/required
12+
*/
13+
14+
import cpp
15+
import codingstandards.c.misra
16+
import codingstandards.cpp.IntegerConstantMacro
17+
import codingstandards.cpp.Literals
18+
19+
predicate matchesSign(IntegerConstantMacro macro, PossiblyNegativeLiteral literal) {
20+
literal.isNegative() implies macro.isSigned()
21+
}
22+
23+
predicate matchesSize(IntegerConstantMacro macro, PossiblyNegativeLiteral literal) {
24+
literal.getRawValue() <= macro.maxValue() and
25+
literal.getRawValue() >= macro.minValue()
26+
}
27+
28+
from
29+
PossiblyNegativeLiteral literal, MacroInvocation invoke, IntegerConstantMacro macro,
30+
string explanation
31+
where
32+
not isExcluded(invoke, Types2Package::incorrectlySizedIntegerConstantMacroArgumentQuery()) and
33+
invoke.getMacro() = macro and
34+
literal = invoke.getExpr() and
35+
(
36+
not matchesSign(macro, literal) and
37+
explanation = " cannot be negative"
38+
or
39+
matchesSign(macro, literal) and
40+
// Wait for BigInt support to check 64 bit macro types.
41+
macro.getSize() < 64 and
42+
not matchesSize(macro, literal) and
43+
explanation = " is outside of the allowed range " + macro.getRangeString()
44+
)
45+
select literal, "Value provided to integer constant macro " + macro.getName() + explanation
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/**
2+
* @id c/misra/integer-constant-macro-argument-uses-suffix
3+
* @name RULE-7-5: The argument of an integer constant macro shall not use literal suffixes u, l, or ul
4+
* @description Integer constant macros should be used integer literal values with no u/l suffix.
5+
* @kind problem
6+
* @precision high
7+
* @problem.severity warning
8+
* @tags external/misra/id/rule-7-5
9+
* readability
10+
* maintainability
11+
* external/misra/c/2012/amendment3
12+
* external/misra/obligation/required
13+
*/
14+
15+
import cpp
16+
import codingstandards.c.misra
17+
import codingstandards.cpp.IntegerConstantMacro
18+
import codingstandards.cpp.Literals
19+
20+
string argumentSuffix(MacroInvocation invoke) {
21+
// Extractor strips the suffix unless we look at the unexpanded argument text.
22+
// Unexpanded argument text can be malformed in all sorts of ways, so make
23+
// this match relatively strict, to be safe.
24+
result = invoke.getUnexpandedArgument(0).regexpCapture("([0-9]+|0[xX][0-9A-F]+)([uUlL]+)$", 2)
25+
}
26+
27+
from MacroInvocation invoke, PossiblyNegativeLiteral argument, string suffix
28+
where
29+
not isExcluded(invoke, Types2Package::integerConstantMacroArgumentUsesSuffixQuery()) and
30+
invoke.getMacro() instanceof IntegerConstantMacro and
31+
invoke.getExpr() = argument and
32+
suffix = argumentSuffix(invoke)
33+
select argument,
34+
"Value suffix '" + suffix + "' is not allowed on provided argument to integer constant macro " +
35+
invoke.getMacroName() + "."
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/**
2+
* @id c/misra/invalid-integer-constant-macro-argument
3+
* @name RULE-7-5: The argument of an integer constant macro shall be a literal
4+
* @description Integer constant macros should be given a literal value as an argument.
5+
* @kind problem
6+
* @precision very-high
7+
* @problem.severity warning
8+
* @tags external/misra/id/rule-7-5
9+
* correctness
10+
* external/misra/c/2012/amendment3
11+
* external/misra/obligation/required
12+
*/
13+
14+
import cpp
15+
import codingstandards.c.misra
16+
import codingstandards.cpp.IntegerConstantMacro
17+
import codingstandards.cpp.Literals
18+
import semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis
19+
20+
from MacroInvocation invoke, IntegerConstantMacro macro
21+
where
22+
not isExcluded(invoke, Types2Package::invalidIntegerConstantMacroArgumentQuery()) and
23+
invoke.getMacro() = macro and
24+
(
25+
not invoke.getExpr() instanceof PossiblyNegativeLiteral
26+
or
27+
any(MacroInvocation inner).getParentInvocation() = invoke
28+
)
29+
select invoke.getExpr(),
30+
"Argument to integer constant macro " + macro.getName() + " must be an integer literal."
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
/**
2+
* @id c/misra/invalid-literal-for-integer-constant-macro-argument
3+
* @name RULE-7-5: The argument of an integer constant macro shall be a decimal, hex, or octal literal
4+
* @description Integer constant macro arguments should be a decimal, hex, or octal literal.
5+
* @kind problem
6+
* @precision very-high
7+
* @problem.severity error
8+
* @tags external/misra/id/rule-7-5
9+
* correctness
10+
* external/misra/c/2012/amendment3
11+
* external/misra/obligation/required
12+
*/
13+
14+
import cpp
15+
import codingstandards.c.misra
16+
import codingstandards.cpp.IntegerConstantMacro
17+
import codingstandards.cpp.Literals
18+
19+
/**
20+
* Floating point literals are not allowed. Neither are char or string
21+
* literals, although those are not `NumericLiteral`s and therefore detected in
22+
* `InvalidIntegerConstantMacroArgument.ql`.
23+
*/
24+
predicate validLiteralType(PossiblyNegativeLiteral literal) {
25+
literal.getBaseLiteral() instanceof Cpp14Literal::DecimalLiteral or
26+
literal.getBaseLiteral() instanceof Cpp14Literal::OctalLiteral or
27+
literal.getBaseLiteral() instanceof Cpp14Literal::HexLiteral or
28+
// Ignore cases where the AST/extractor don't give us enough information:
29+
literal.getBaseLiteral() instanceof Cpp14Literal::UnrecognizedNumericLiteral
30+
}
31+
32+
/**
33+
* Clang accepts `xINTsize_C(0b01)`, and expands the argument into a decimal
34+
* literal. Binary literals are not standard c nor are they allowed by rule 7-5.
35+
* Detect this pattern before macro expansion.
36+
*/
37+
predicate seemsBinaryLiteral(MacroInvocation invoke) {
38+
invoke.getUnexpandedArgument(0).regexpMatch("-?0[bB][01]+")
39+
}
40+
41+
/**
42+
* Extractor converts `xINTsize_C('a')` to a decimal literal. Therefore, detect
43+
* this pattern before macro expansion.
44+
*/
45+
predicate seemsCharLiteral(MacroInvocation invoke) {
46+
invoke.getUnexpandedArgument(0).regexpMatch("-?'\\\\?.'")
47+
}
48+
49+
string explainIncorrectArgument(MacroInvocation invoke) {
50+
if seemsBinaryLiteral(invoke)
51+
then result = "binary literal"
52+
else
53+
if seemsCharLiteral(invoke)
54+
then result = "char literal"
55+
else
56+
exists(PossiblyNegativeLiteral literal |
57+
literal = invoke.getExpr() and
58+
if literal.getBaseLiteral() instanceof Cpp14Literal::FloatingLiteral
59+
then result = "floating point literal"
60+
else result = "invalid literal"
61+
)
62+
}
63+
64+
from MacroInvocation invoke, PossiblyNegativeLiteral literal
65+
where
66+
not isExcluded(invoke, Types2Package::invalidLiteralForIntegerConstantMacroArgumentQuery()) and
67+
invoke.getMacro() instanceof IntegerConstantMacro and
68+
literal = invoke.getExpr() and
69+
(
70+
not validLiteralType(literal) or
71+
seemsBinaryLiteral(invoke) or
72+
seemsCharLiteral(invoke)
73+
)
74+
select literal,
75+
"Integer constant macro " + invoke.getMacroName() + " used with " +
76+
explainIncorrectArgument(invoke) +
77+
" argument, only decimal, octal, or hex integer literal allowed."
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
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/c/2012/amendment3
12+
* external/misra/obligation/required
13+
*/
14+
15+
import cpp
16+
import codingstandards.c.misra
17+
import codingstandards.cpp.IntegerConstantMacro
18+
19+
from MacroInvocation macroInvoke, IntegerConstantMacro macro
20+
where
21+
not isExcluded(macroInvoke, Types2Package::useOfBannedSmallIntegerConstantMacroQuery()) and
22+
macroInvoke.getMacro() = macro and
23+
macro.isSmall()
24+
select macroInvoke, "Usage of small integer constant macro " + macro.getName() + " is not allowed."
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
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: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
rules/RULE-7-5/IncorrectlySizedIntegerConstantMacroArgument.ql
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
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: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
rules/RULE-7-5/IntegerConstantMacroArgumentUsesSuffix.ql
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
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: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. |
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
rules/RULE-7-5/InvalidIntegerConstantMacroArgument.ql
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
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. |
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
rules/RULE-7-5/InvalidLiteralForIntegerConstantMacroArgument.ql

0 commit comments

Comments
 (0)