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 a2943f6

Browse filesBrowse files
authored
Merge branch 'main' into rp/m0-1-10-711
2 parents 3bedebb + dcab086 commit a2943f6
Copy full SHA for a2943f6

File tree

Expand file treeCollapse file tree

50 files changed

+1226
-53
lines changed
Filter options

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Dismiss banner
Expand file treeCollapse file tree

50 files changed

+1226
-53
lines changed

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

Copy file name to clipboardExpand all lines: c/misra/src/codingstandards/c/misra/EssentialTypes.qll
+44-4Lines changed: 44 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -130,12 +130,17 @@ EssentialTypeCategory getEssentialTypeCategory(Type type) {
130130
essentialType.(IntegralType).isSigned() and
131131
not essentialType instanceof PlainCharType
132132
or
133+
// Anonymous enums are considered to be signed
134+
result = EssentiallySignedType() and
135+
essentialType instanceof AnonymousEnumType and
136+
not essentialType instanceof MisraBoolType
137+
or
133138
result = EssentiallyUnsignedType() and
134139
essentialType.(IntegralType).isUnsigned() and
135140
not essentialType instanceof PlainCharType
136141
or
137142
result = EssentiallyEnumType() and
138-
essentialType instanceof Enum and
143+
essentialType instanceof NamedEnumType and
139144
not essentialType instanceof MisraBoolType
140145
or
141146
result = EssentiallyFloatingType() and
@@ -348,16 +353,51 @@ class EssentialBinaryArithmeticExpr extends EssentialExpr, BinaryArithmeticOpera
348353
}
349354
}
350355

356+
/**
357+
* A named Enum type, as per D.5.
358+
*/
359+
class NamedEnumType extends Enum {
360+
NamedEnumType() {
361+
not isAnonymous()
362+
or
363+
exists(Type useOfEnum | this = useOfEnum.stripType() |
364+
exists(TypedefType t | t.getBaseType() = useOfEnum)
365+
or
366+
exists(Function f | f.getType() = useOfEnum or f.getAParameter().getType() = useOfEnum)
367+
or
368+
exists(Struct s | s.getAField().getType() = useOfEnum)
369+
or
370+
exists(Variable v | v.getType() = useOfEnum)
371+
)
372+
}
373+
}
374+
375+
/**
376+
* An anonymous Enum type, as per D.5.
377+
*/
378+
class AnonymousEnumType extends Enum {
379+
AnonymousEnumType() { not this instanceof NamedEnumType }
380+
}
381+
382+
/**
383+
* The EssentialType of an EnumConstantAccess, which may be essentially enum or essentially signed.
384+
*/
351385
class EssentialEnumConstantAccess extends EssentialExpr, EnumConstantAccess {
352-
override Type getEssentialType() { result = getTarget().getDeclaringEnum() }
386+
override Type getEssentialType() {
387+
exists(Enum e | e = getTarget().getDeclaringEnum() |
388+
if e instanceof NamedEnumType then result = e else result = stlr(this)
389+
)
390+
}
353391
}
354392

355393
class EssentialLiteral extends EssentialExpr, Literal {
356394
override Type getEssentialType() {
357395
if this instanceof BooleanLiteral
358-
then result instanceof MisraBoolType
396+
then
397+
// This returns a multitude of types - not sure if we really want that
398+
result instanceof MisraBoolType
359399
else (
360-
if this.(CharLiteral).getCharacter().length() = 1
400+
if this instanceof CharLiteral
361401
then result instanceof PlainCharType
362402
else
363403
exists(Type underlyingStandardType |

‎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
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ where
3838
// be reported as non-compliant.
3939
leftOpTypeCategory = EssentiallyEnumType() and
4040
rightOpTypeCategory = EssentiallyEnumType() and
41-
not leftOpEssentialType = rightOpEssentialType and
41+
not leftOpEssentialType.getUnspecifiedType() = rightOpEssentialType.getUnspecifiedType() and
4242
message =
4343
"The operands of this operator with usual arithmetic conversions have mismatched essentially Enum types (left operand: "
4444
+ leftOpEssentialType + ", right operand: " + rightOpEssentialType + ")."

‎c/misra/src/rules/RULE-11-5/ConversionFromPointerToVoidIntoPointerToObject.ql

Copy file name to clipboardExpand all lines: c/misra/src/rules/RULE-11-5/ConversionFromPointerToVoidIntoPointerToObject.ql
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import codingstandards.cpp.Pointers
1919
from Cast cast, VoidPointerType type, PointerToObjectType newType
2020
where
2121
not isExcluded(cast, Pointers1Package::conversionFromPointerToVoidIntoPointerToObjectQuery()) and
22-
type = cast.getExpr().getUnderlyingType() and
22+
type = cast.getExpr().getUnspecifiedType() and
2323
newType = cast.getUnderlyingType() and
2424
not isNullPointerConstant(cast.getExpr())
2525
select cast,

‎c/misra/src/rules/RULE-2-2/DeadCode.ql

Copy file name to clipboardExpand all lines: c/misra/src/rules/RULE-2-2/DeadCode.ql
+78-3Lines changed: 78 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,83 @@
1515

1616
import cpp
1717
import codingstandards.c.misra
18-
import codingstandards.cpp.rules.deadcode.DeadCode
18+
import codingstandards.cpp.alertreporting.HoldsForAllCopies
19+
import codingstandards.cpp.deadcode.UselessAssignments
1920

20-
class MisraCDeadCodeQuery extends DeadCodeSharedQuery {
21-
MisraCDeadCodeQuery() { this = DeadCodePackage::deadCodeQuery() }
21+
/**
22+
* Gets an explicit cast from `e` if one exists.
23+
*/
24+
Cast getExplicitCast(Expr e) {
25+
exists(Conversion c | c = e.getExplicitlyConverted() |
26+
result = c
27+
or
28+
result = c.(ParenthesisExpr).getExpr()
29+
)
30+
}
31+
32+
class ExprStmtExpr extends Expr {
33+
ExprStmtExpr() { exists(ExprStmt es | es.getExpr() = this) }
34+
}
35+
36+
/**
37+
* An "operation" as defined by MISRA C Rule 2.2 that is dead, i.e. it's removal has no effect on
38+
* the behaviour of the program.
39+
*/
40+
class DeadOperationInstance extends Expr {
41+
string description;
42+
43+
DeadOperationInstance() {
44+
// Exclude cases nested within macro expansions, because the code may be "live" in other
45+
// expansions
46+
isNotWithinMacroExpansion(this) and
47+
exists(ExprStmtExpr e |
48+
if exists(getExplicitCast(e))
49+
then
50+
this = getExplicitCast(e) and
51+
// void conversions are permitted
52+
not getExplicitCast(e) instanceof VoidConversion and
53+
description = "Cast operation is unused"
54+
else (
55+
this = e and
56+
(
57+
if e instanceof Assignment
58+
then
59+
exists(SsaDefinition sd, LocalScopeVariable v |
60+
e = sd.getDefinition() and
61+
sd.getDefiningValue(v).isPure() and
62+
// The definition is useless
63+
isUselessSsaDefinition(sd, v) and
64+
description = "Assignment to " + v.getName() + " is unused and has no side effects"
65+
)
66+
else (
67+
e.isPure() and
68+
description = "Result of operation is unused and has no side effects"
69+
)
70+
)
71+
)
72+
)
73+
}
74+
75+
string getDescription() { result = description }
2276
}
77+
78+
class DeadOperation = HoldsForAllCopies<DeadOperationInstance, Expr>::LogicalResultElement;
79+
80+
from
81+
DeadOperation deadOperation, DeadOperationInstance instance, string message, Element explainer,
82+
string explainerDescription
83+
where
84+
not isExcluded(instance, DeadCodePackage::deadCodeQuery()) and
85+
instance = deadOperation.getAnElementInstance() and
86+
if instance instanceof FunctionCall
87+
then
88+
message = instance.getDescription() + " from call to function $@" and
89+
explainer = instance.(FunctionCall).getTarget() and
90+
explainerDescription = explainer.(Function).getName()
91+
else (
92+
message = instance.getDescription() and
93+
// Ignore the explainer
94+
explainer = instance and
95+
explainerDescription = ""
96+
)
97+
select deadOperation, message + ".", explainer, explainerDescription
+45Lines 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
+35Lines 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() + "."
+30Lines 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."
+77Lines 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."
+24Lines 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."

0 commit comments

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