Skip to content

Commit 41fdd0a

Browse files
committed
Merge branch 'main' into lcartey/produce-ql-packs
2 parents c7f04f5 + 09a2de8 commit 41fdd0a

File tree

95 files changed

+1639
-99
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

95 files changed

+1639
-99
lines changed

c/cert/src/qlpack.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name: codeql/cert-c-coding-standards
2-
version: 2.36.0-dev
2+
version: 2.37.0-dev
33
description: CERT C 2016
44
suites: codeql-suites
55
license: MIT

c/cert/test/qlpack.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name: codeql/cert-c-coding-standards-tests
2-
version: 2.36.0-dev
2+
version: 2.37.0-dev
33
extractor: cpp
44
license: MIT
55
dependencies:

c/common/src/qlpack.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name: codeql/common-c-coding-standards
2-
version: 2.36.0-dev
2+
version: 2.37.0-dev
33
license: MIT
44
dependencies:
55
codeql/common-cpp-coding-standards: '*'

c/common/test/qlpack.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name: codeql/common-c-coding-standards-tests
2-
version: 2.36.0-dev
2+
version: 2.37.0-dev
33
extractor: cpp
44
license: MIT
55
dependencies:

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

Lines 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/qlpack.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name: codeql/misra-c-coding-standards
2-
version: 2.36.0-dev
2+
version: 2.37.0-dev
33
description: MISRA C 2012
44
suites: codeql-suites
55
license: MIT

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

Lines 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

Lines 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

Lines 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
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/**
2+
* @id c/misra/call-to-banned-random-function
3+
* @name RULE-21-24: The random number generator functions of <stdlib.h> shall not be used
4+
* @description The standard functions rand() and srand() will not give high quality random results
5+
* in all implementations and are therefore banned.
6+
* @kind problem
7+
* @precision very-high
8+
* @problem.severity warning
9+
* @tags external/misra/id/rule-21-24
10+
* security
11+
* external/misra/c/2012/amendment3
12+
* external/misra/obligation/required
13+
*/
14+
15+
import cpp
16+
import codingstandards.c.misra
17+
18+
from FunctionCall call, string name
19+
where
20+
not isExcluded(call, Banned2Package::callToBannedRandomFunctionQuery()) and
21+
name = ["rand", "srand"] and
22+
call.getTarget().hasGlobalOrStdName(name)
23+
select call, "Call to banned random number generation function '" + name + "'."

0 commit comments

Comments
 (0)