Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 2526a88

Browse filesBrowse files
authored
Merge pull request #822 from github/michaelrfairhurst/address-rule-amendments-from-amd3
Michaelrfairhurst/address rule amendments from amd3
2 parents 8c88c43 + 1373292 commit 2526a88
Copy full SHA for 2526a88

30 files changed

+1102
-599
lines changed

‎amendments.csv

Copy file name to clipboardExpand all lines: amendments.csv
+7-7Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
language,standard,amendment,rule_id,supportable,implementation_category,implemented,difficulty
2-
c,MISRA-C-2012,Amendment3,DIR-4-6,Yes,Expand,No,Easy
2+
c,MISRA-C-2012,Amendment3,DIR-4-6,Yes,Expand,Yes,Easy
33
c,MISRA-C-2012,Amendment3,DIR-4-9,Yes,Refine,No,Easy
44
c,MISRA-C-2012,Amendment3,DIR-4-11,Yes,Refine,No,Import
55
c,MISRA-C-2012,Amendment3,RULE-1-4,Yes,Replace,No,Easy
6-
c,MISRA-C-2012,Amendment3,RULE-10-1,Yes,Replace,No,Easy
7-
c,MISRA-C-2012,Amendment3,RULE-10-3,Yes,Refine,No,Easy
8-
c,MISRA-C-2012,Amendment3,RULE-10-4,Yes,Refine,No,Import
9-
c,MISRA-C-2012,Amendment3,RULE-10-5,Yes,Expand,No,Easy
10-
c,MISRA-C-2012,Amendment3,RULE-10-7,Yes,Refine,No,Import
11-
c,MISRA-C-2012,Amendment3,RULE-10-8,Yes,Refine,No,Import
6+
c,MISRA-C-2012,Amendment3,RULE-10-1,Yes,Replace,Yes,Easy
7+
c,MISRA-C-2012,Amendment3,RULE-10-3,Yes,Refine,Yes,Easy
8+
c,MISRA-C-2012,Amendment3,RULE-10-4,Yes,Refine,Yes,Import
9+
c,MISRA-C-2012,Amendment3,RULE-10-5,Yes,Expand,Yes,Easy
10+
c,MISRA-C-2012,Amendment3,RULE-10-7,Yes,Refine,Yes,Import
11+
c,MISRA-C-2012,Amendment3,RULE-10-8,Yes,Refine,Yes,Import
1212
c,MISRA-C-2012,Amendment3,RULE-21-11,Yes,Clarification,Yes,Import
1313
c,MISRA-C-2012,Amendment3,RULE-21-12,Yes,Replace,No,Easy
1414
c,MISRA-C-2012,Amendment4,RULE-11-3,Yes,Expand,No,Easy

‎c/misra/src/codingstandards/c/misra/EssentialTypes.qll

Copy file name to clipboardExpand all lines: c/misra/src/codingstandards/c/misra/EssentialTypes.qll
+24-4Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,17 @@ import codingstandards.c.misra
66
import semmle.code.cpp.rangeanalysis.RangeAnalysisUtils
77
import MisraExpressions
88

9+
newtype TEssentialFloatCategory =
10+
Real() or
11+
Complex()
12+
913
newtype TEssentialTypeCategory =
1014
EssentiallyBooleanType() or
1115
EssentiallyCharacterType() or
1216
EssentiallyEnumType() or
1317
EssentiallySignedType() or
1418
EssentiallyUnsignedType() or
15-
EssentiallyFloatingType()
19+
EssentiallyFloatingType(TEssentialFloatCategory c)
1620

1721
/** An essential type category, as specified by Appendix D.1. */
1822
class EssentialTypeCategory extends TEssentialTypeCategory {
@@ -27,7 +31,9 @@ class EssentialTypeCategory extends TEssentialTypeCategory {
2731
or
2832
this = EssentiallyUnsignedType() and result = "essentially Unsigned type"
2933
or
30-
this = EssentiallyFloatingType() and result = "essentially Floating type"
34+
this = EssentiallyFloatingType(Real()) and result = "essentially Floating type"
35+
or
36+
this = EssentiallyFloatingType(Complex()) and result = "essentially Complex Floating type"
3137
}
3238
}
3339

@@ -145,8 +151,11 @@ EssentialTypeCategory getEssentialTypeCategory(Type type) {
145151
essentialType instanceof NamedEnumType and
146152
not essentialType instanceof MisraBoolType
147153
or
148-
result = EssentiallyFloatingType() and
149-
essentialType instanceof FloatingPointType
154+
result = EssentiallyFloatingType(Real()) and
155+
essentialType instanceof RealNumberType
156+
or
157+
result = EssentiallyFloatingType(Complex()) and
158+
essentialType instanceof ComplexNumberType
150159
)
151160
}
152161

@@ -168,6 +177,17 @@ Type getEssentialType(Expr e) {
168177

169178
Type getEssentialTypeBeforeConversions(Expr e) { result = e.(EssentialExpr).getEssentialType() }
170179

180+
/**
181+
* For most essential types, `Type.getSize()` is correct, except for complex floating types.
182+
*
183+
* For complex floating types, the size is the size of the real part, so we divide by 2.
184+
*/
185+
int getEssentialSize(Type essentialType) {
186+
if getEssentialTypeCategory(essentialType) = EssentiallyFloatingType(Complex())
187+
then result = essentialType.getSize() / 2
188+
else result = essentialType.getSize()
189+
}
190+
171191
class EssentialExpr extends Expr {
172192
Type getEssentialType() { result = this.getType() }
173193

‎c/misra/src/rules/DIR-4-6/PlainNumericalTypeUsedOverExplicitTypedef.ql

Copy file name to clipboardExpand all lines: c/misra/src/rules/DIR-4-6/PlainNumericalTypeUsedOverExplicitTypedef.ql
+51-7Lines changed: 51 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ class BuiltInNumericType extends BuiltInType {
2929
this instanceof DoubleType
3030
or
3131
this instanceof LongDoubleType
32+
or
33+
this instanceof ComplexNumberType
3234
}
3335
}
3436

@@ -38,22 +40,64 @@ predicate forbiddenBuiltinNumericUsedInDecl(Variable var, string message) {
3840
message = "The type " + var.getType() + " is not a fixed-width numeric type."
3941
}
4042

43+
class SizedTypeString extends string {
44+
string pattern;
45+
int size;
46+
47+
bindingset[this]
48+
pragma[inline]
49+
SizedTypeString() {
50+
pattern = "(u?int|c?float)(4|8|16|32|64|128)_t" and
51+
this.regexpMatch(pattern) and
52+
size = this.regexpCapture(pattern, 2).toInt()
53+
}
54+
55+
bindingset[this]
56+
pragma[inline]
57+
int getSize() { result = size }
58+
59+
bindingset[this]
60+
pragma[inline]
61+
predicate isComplex() { this.charAt(0) = "c" }
62+
}
63+
64+
predicate forbiddenComplexType(CTypedefType typedef, string message) {
65+
typedef.getName().(SizedTypeString).isComplex() and
66+
(
67+
if typedef.getBaseType().stripTopLevelSpecifiers() instanceof ComplexNumberType
68+
then
69+
typedef.getSize() * 8 != typedef.getName().(SizedTypeString).getSize() * 2 and
70+
message = "The typedef type " + typedef.getName() + " does not have its indicated real size."
71+
else message = "The typedef type " + typedef.getName() + " is not a complex type."
72+
)
73+
}
74+
75+
predicate forbiddenRealType(CTypedefType typedef, string message) {
76+
not typedef.getName().(SizedTypeString).isComplex() and
77+
(
78+
if typedef.getBaseType().stripTopLevelSpecifiers() instanceof ComplexNumberType
79+
then message = "The typedef name " + typedef.getName() + " does not indicate a complex type."
80+
else (
81+
typedef.getSize() * 8 != typedef.getName().(SizedTypeString).getSize() and
82+
message = "The typedef type " + typedef.getName() + " does not have its indicated size."
83+
)
84+
)
85+
}
86+
4187
predicate forbiddenTypedef(CTypedefType typedef, string message) {
4288
/* If the typedef's name contains an explicit size */
4389
(
44-
if typedef.getName().regexpMatch("u?(int|float)(4|8|16|32|64|128)_t")
90+
if typedef.getName() instanceof SizedTypeString
4591
then (
46-
/* Then the actual type size should match. */
47-
not typedef.getSize() * 8 =
48-
// times 8 because getSize() gets the size in bytes
49-
typedef.getName().regexpCapture("u?(int|float)(4|8|16|32|64|128)_t", 2).toInt() and
50-
message = "The typedef type " + typedef.getName() + " does not have its indicated size."
92+
forbiddenRealType(typedef, message)
93+
or
94+
forbiddenComplexType(typedef, message)
5195
) else (
5296
(
5397
// type def is to a built in numeric type
5498
typedef.getBaseType() instanceof BuiltInNumericType and
5599
// but does not include the size in the name
56-
not typedef.getName().regexpMatch("u?(int|float)(4|8|16|32|64|128)_t")
100+
not typedef.getName() instanceof SizedTypeString
57101
or
58102
// this is a typedef to a forbidden type def
59103
forbiddenTypedef(typedef.getBaseType(), _)

‎c/misra/src/rules/RULE-10-1/OperandsOfAnInappropriateEssentialType.ql

Copy file name to clipboardExpand all lines: c/misra/src/rules/RULE-10-1/OperandsOfAnInappropriateEssentialType.ql
+57-11Lines changed: 57 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,15 @@ import cpp
1616
import codingstandards.c.misra
1717
import codingstandards.c.misra.EssentialTypes
1818

19+
predicate hasComparableFloatValue(Expr e) {
20+
exists(float value |
21+
value = e.getValue().toFloat() or
22+
value = -e.(UnaryMinusExpr).getOperand().getValue().toFloat()
23+
|
24+
value in [0.0, "Infinity".toFloat(), -"Infinity".toFloat()]
25+
)
26+
}
27+
1928
/**
2029
* Holds if the operator `operator` has an operand `child` that is of an inappropriate essential type
2130
* according to MISRA C 2012 Rule 10.1.
@@ -33,8 +42,11 @@ predicate isInappropriateEssentialType(
3342
etc = EssentiallyCharacterType() and
3443
rationaleId = 4
3544
or
36-
etc = EssentiallyFloatingType() and
45+
etc = EssentiallyFloatingType(Real()) and
3746
rationaleId = 1
47+
or
48+
etc = EssentiallyFloatingType(Complex()) and
49+
rationaleId = 9
3850
)
3951
or
4052
child = operator.(UnaryPlusExpr).getOperand() and
@@ -64,8 +76,6 @@ predicate isInappropriateEssentialType(
6476
rationaleId = 8
6577
)
6678
or
67-
// The table only talks about + and -, but below it clarifies ++ and -- are also considered to
68-
// be equivalent.
6979
child =
7080
[
7181
operator.(AddExpr).getAnOperand(), operator.(SubExpr).getAnOperand(),
@@ -80,6 +90,13 @@ predicate isInappropriateEssentialType(
8090
rationaleId = 5
8191
)
8292
or
93+
child =
94+
[operator.(IncrementOperation).getAnOperand(), operator.(DecrementOperation).getAnOperand()] and
95+
(
96+
etc = EssentiallyFloatingType(Complex()) and
97+
rationaleId = 9
98+
)
99+
or
83100
child =
84101
[
85102
operator.(DivExpr).getAnOperand(), operator.(MulExpr).getAnOperand(),
@@ -107,13 +124,26 @@ predicate isInappropriateEssentialType(
107124
etc = EssentiallyEnumType() and
108125
rationaleId = 5
109126
or
110-
etc = EssentiallyFloatingType() and
127+
etc = EssentiallyFloatingType(Real()) and
111128
rationaleId = 1
129+
or
130+
etc = EssentiallyFloatingType(Complex()) and
131+
rationaleId = 9
112132
)
113133
or
114134
child = operator.(RelationalOperation).getAnOperand() and
115-
etc = EssentiallyBooleanType() and
116-
rationaleId = 3
135+
(
136+
etc = EssentiallyBooleanType() and
137+
rationaleId = 3
138+
or
139+
etc = EssentiallyFloatingType(Complex()) and
140+
rationaleId = 9
141+
)
142+
or
143+
child = operator.(EqualityOperation).getAnOperand() and
144+
rationaleId = 10 and
145+
not hasComparableFloatValue(operator.(EqualityOperation).getAnOperand()) and
146+
etc = EssentiallyFloatingType(_)
117147
or
118148
child = [operator.(NotExpr).getAnOperand(), operator.(BinaryLogicalOperation).getAnOperand()] and
119149
rationaleId = 2 and
@@ -126,7 +156,7 @@ predicate isInappropriateEssentialType(
126156
or
127157
etc = EssentiallyUnsignedType()
128158
or
129-
etc = EssentiallyFloatingType()
159+
etc = EssentiallyFloatingType(_)
130160
)
131161
or
132162
child =
@@ -147,8 +177,11 @@ predicate isInappropriateEssentialType(
147177
etc = EssentiallySignedType() and
148178
rationaleId = 6
149179
or
150-
etc = EssentiallyFloatingType() and
180+
etc = EssentiallyFloatingType(Real()) and
151181
rationaleId = 1
182+
or
183+
etc = EssentiallyFloatingType(Complex()) and
184+
rationaleId = 9
152185
)
153186
or
154187
child =
@@ -171,8 +204,11 @@ predicate isInappropriateEssentialType(
171204
etc = EssentiallySignedType() and
172205
rationaleId = 7
173206
or
174-
etc = EssentiallyFloatingType() and
207+
etc = EssentiallyFloatingType(Real()) and
175208
rationaleId = 1
209+
or
210+
etc = EssentiallyFloatingType(Complex()) and
211+
rationaleId = 9
176212
)
177213
or
178214
child =
@@ -197,8 +233,11 @@ predicate isInappropriateEssentialType(
197233
etc = EssentiallySignedType() and
198234
rationaleId = 6
199235
or
200-
etc = EssentiallyFloatingType() and
236+
etc = EssentiallyFloatingType(Real()) and
201237
rationaleId = 1
238+
or
239+
etc = EssentiallyFloatingType(Complex()) and
240+
rationaleId = 9
202241
)
203242
or
204243
child = operator.(ConditionalExpr).getCondition() and
@@ -215,7 +254,7 @@ predicate isInappropriateEssentialType(
215254
etc = EssentiallyUnsignedType() and
216255
rationaleId = 2
217256
or
218-
etc = EssentiallyFloatingType() and
257+
etc = EssentiallyFloatingType(_) and
219258
rationaleId = 2
220259
)
221260
)
@@ -245,6 +284,13 @@ string getRationaleMessage(int rationaleId, EssentialTypeCategory etc) {
245284
rationaleId = 8 and
246285
result =
247286
"Operand of essentially Unsigned type will be converted to a signed type with the signedness dependent on the implemented size of int."
287+
or
288+
rationaleId = 9 and
289+
result = "Use of essentially Complex type in this way is a constraint violation."
290+
or
291+
rationaleId = 10 and
292+
result =
293+
"Floating point numbers have inherent error such that comparisons should consider precision and not exact equality."
248294
}
249295

250296
from Expr operator, Expr child, int rationaleId, EssentialTypeCategory etc

‎c/misra/src/rules/RULE-10-3/AssignmentOfIncompatibleEssentialType.ql

Copy file name to clipboardExpand all lines: c/misra/src/rules/RULE-10-3/AssignmentOfIncompatibleEssentialType.ql
+6Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,5 +48,11 @@ where
4848
lValueTypeCategory = EssentiallyUnsignedType() and
4949
const >= 0 and
5050
const <= 2.pow(lValueEssentialType.getSize() * 8)
51+
) and
52+
// Exception 4: Real floating point values may be assignable to complex floating point values
53+
not (
54+
lValueTypeCategory = EssentiallyFloatingType(Complex()) and
55+
rValueTypeCategory = EssentiallyFloatingType(Real()) and
56+
lValueEssentialType.getSize() >= rValueEssentialType.getSize() * 2
5157
)
5258
select rValue, message

‎c/misra/src/rules/RULE-10-4/OperandsWithMismatchedEssentialTypeCategory.ql

Copy file name to clipboardExpand all lines: c/misra/src/rules/RULE-10-4/OperandsWithMismatchedEssentialTypeCategory.ql
+5Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,11 @@ where
3030
rightOpTypeCategory = getEssentialTypeCategory(rightOpEssentialType) and
3131
(
3232
not leftOpTypeCategory = rightOpTypeCategory and
33+
not (
34+
// Exception 3: Operands where both are real or complex floating types are allowed.
35+
leftOpTypeCategory = EssentiallyFloatingType(_) and
36+
rightOpTypeCategory = EssentiallyFloatingType(_)
37+
) and
3338
message =
3439
"The operands of this operator with usual arithmetic conversions have mismatched essential types (left operand: "
3540
+ leftOpTypeCategory + ", right operand: " + rightOpTypeCategory + ")."

‎c/misra/src/rules/RULE-10-5/InappropriateEssentialTypeCast.ql

Copy file name to clipboardExpand all lines: c/misra/src/rules/RULE-10-5/InappropriateEssentialTypeCast.ql
+3-3Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,14 @@ predicate isIncompatibleEssentialTypeCast(EssentialTypeCategory fromCat, Essenti
2323
toCat =
2424
[
2525
EssentiallyCharacterType(), EssentiallyEnumType(), EssentiallySignedType(),
26-
EssentiallyUnsignedType(), EssentiallyFloatingType().(TEssentialTypeCategory)
26+
EssentiallyUnsignedType(), EssentiallyFloatingType(_).(TEssentialTypeCategory)
2727
]
2828
or
2929
fromCat = EssentiallyCharacterType() and
3030
toCat =
3131
[
3232
EssentiallyBooleanType(), EssentiallyEnumType(),
33-
EssentiallyFloatingType().(TEssentialTypeCategory)
33+
EssentiallyFloatingType(_).(TEssentialTypeCategory)
3434
]
3535
or
3636
fromCat = EssentiallyEnumType() and
@@ -42,7 +42,7 @@ predicate isIncompatibleEssentialTypeCast(EssentialTypeCategory fromCat, Essenti
4242
fromCat = EssentiallyUnsignedType() and
4343
toCat = [EssentiallyBooleanType(), EssentiallyEnumType().(TEssentialTypeCategory)]
4444
or
45-
fromCat = EssentiallyFloatingType() and
45+
fromCat = EssentiallyFloatingType(_) and
4646
toCat =
4747
[
4848
EssentiallyBooleanType(), EssentiallyCharacterType(),

‎c/misra/src/rules/RULE-10-7/ImplicitConversionOfCompositeExpression.ql

Copy file name to clipboardExpand all lines: c/misra/src/rules/RULE-10-7/ImplicitConversionOfCompositeExpression.ql
+5-1Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@ bindingset[essentialTypeLeft, essentialTypeRight]
2323
pragma[inline_late]
2424
predicate isSameEssentialTypeCategory(Type essentialTypeLeft, Type essentialTypeRight) {
2525
getEssentialTypeCategory(essentialTypeLeft) = getEssentialTypeCategory(essentialTypeRight)
26+
or
27+
// Complex and real floating types are considered interchangeable
28+
getEssentialTypeCategory(essentialTypeLeft) = EssentiallyFloatingType(_) and
29+
getEssentialTypeCategory(essentialTypeRight) = EssentiallyFloatingType(_)
2630
}
2731

2832
from
@@ -35,7 +39,7 @@ where
3539
not otherOp = compositeOp and
3640
compositeEssentialType = getEssentialType(compositeOp) and
3741
otherOpEssentialType = getEssentialType(otherOp) and
38-
compositeEssentialType.getSize() < otherOpEssentialType.getSize() and
42+
getEssentialSize(compositeEssentialType) < getEssentialSize(otherOpEssentialType) and
3943
// Operands of a different type category in an operation with the usual arithmetic conversions is
4044
// prohibited by Rule 10.4, so we only report cases here where the essential type categories are
4145
// the same

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.