Skip to content

Commit 712d76e

Browse files
committed
Declarations7: add RULE-18-8
1 parent 2c971a6 commit 712d76e

File tree

7 files changed

+117
-2
lines changed

7 files changed

+117
-2
lines changed
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/**
2+
* @id c/misra/variable-length-array-types-used
3+
* @name RULE-18-8: Variable-length array types shall not be used
4+
* @description Using a variable length array can lead to unexpected or undefined program behaviour.
5+
* @kind problem
6+
* @precision very-high
7+
* @problem.severity error
8+
* @tags external/misra/id/rule-18-8
9+
* correctness
10+
* readability
11+
* external/misra/obligation/required
12+
*/
13+
14+
import cpp
15+
import codingstandards.c.misra
16+
17+
predicate partOfConstantExpr(MacroInvocation i) {
18+
exists(Expr e |
19+
e.isConstant() and
20+
not i.getExpr() = e and
21+
i.getExpr().getParent+() = e
22+
)
23+
}
24+
25+
/**
26+
* A variable length array (VLA)
27+
* ie an array where the size
28+
* is not an integer constant expression
29+
*/
30+
class VariableLengthArray extends VariableDeclarationEntry {
31+
VariableLengthArray() {
32+
//VLAs will not have: static/extern specifiers (compilation error)
33+
not this.hasSpecifier("static") and
34+
not this.hasSpecifier("extern") and
35+
//VLAs are not allowed to be initialized
36+
not this.getDeclaration().hasInitializer() and
37+
exists(ArrayType a |
38+
//a.hasArraySize() does not catch multidimensional VLAs like a[1][]
39+
a.toString().matches("%[]%") and
40+
this.getUnspecifiedType() = a and
41+
//variable length array is one declared in block or function prototype
42+
(
43+
this.getDeclaration().getParentScope() instanceof Function or
44+
this.getDeclaration().getParentScope() instanceof BlockStmt
45+
)
46+
)
47+
}
48+
}
49+
50+
from VariableLengthArray v
51+
where
52+
not isExcluded(v, Declarations7Package::variableLengthArrayTypesUsedQuery()) and
53+
//an exception, argv in : int main(int argc, char *argv[])
54+
not v.getDeclaration().getParentScope().(Function).hasName("main")
55+
select v, "Variable length array declared."
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
WARNING: Unused predicate partOfConstantExpr (/Users/knewbury/Desktop/GITHUB/coding-standards/codeql-coding-standards/c/misra/src/rules/RULE-18-8/VariableLengthArrayTypesUsed.ql:17,11-29)
2+
| test.c:3:19:3:20 | definition of pa | Variable length array declared. |
3+
| test.c:6:7:6:8 | definition of a1 | Variable length array declared. |
4+
| test.c:7:7:7:8 | definition of a2 | Variable length array declared. |
5+
| test.c:8:7:8:8 | definition of a3 | Variable length array declared. |
6+
| test.c:14:20:14:21 | definition of pa | Variable length array declared. |
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
rules/RULE-18-8/VariableLengthArrayTypesUsed.ql

c/misra/test/rules/RULE-18-8/test.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#define TEST 1
2+
3+
void f(int n, int pa[1][n]) { // NON_COMPLIANT
4+
int a[1]; // COMPLIANT
5+
int x = 1;
6+
int a1[1 + x]; // NON_COMPLIANT - not integer constant expr
7+
int a2[n]; // NON_COMPLIANT
8+
int a3[1][n]; // NON_COMPLIANT
9+
int a4[] = {1}; // COMPLIANT - not a VLA
10+
int a5[TEST]; // COMPLIANT
11+
int a6[1 + 1]; // COMPLIANT
12+
}
13+
14+
void f1(int n, int pa[n]) { // NON_COMPLIANT
15+
}

cpp/common/src/codingstandards/cpp/exclusions/c/Declarations7.qll

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,20 @@ import cpp
33
import RuleMetadata
44
import codingstandards.cpp.exclusions.RuleMetadata
55

6-
newtype Declarations7Query = TValueImplicitEnumerationConstantNotUniqueQuery()
6+
newtype Declarations7Query =
7+
TVariableLengthArrayTypesUsedQuery() or
8+
TValueImplicitEnumerationConstantNotUniqueQuery()
79

810
predicate isDeclarations7QueryMetadata(Query query, string queryId, string ruleId, string category) {
11+
query =
12+
// `Query` instance for the `variableLengthArrayTypesUsed` query
13+
Declarations7Package::variableLengthArrayTypesUsedQuery() and
14+
queryId =
15+
// `@id` for the `variableLengthArrayTypesUsed` query
16+
"c/misra/variable-length-array-types-used" and
17+
ruleId = "RULE-18-8" and
18+
category = "required"
19+
or
920
query =
1021
// `Query` instance for the `valueImplicitEnumerationConstantNotUnique` query
1122
Declarations7Package::valueImplicitEnumerationConstantNotUniqueQuery() and
@@ -17,6 +28,13 @@ predicate isDeclarations7QueryMetadata(Query query, string queryId, string ruleI
1728
}
1829

1930
module Declarations7Package {
31+
Query variableLengthArrayTypesUsedQuery() {
32+
//autogenerate `Query` type
33+
result =
34+
// `Query` type for `variableLengthArrayTypesUsed` query
35+
TQueryC(TDeclarations7PackageQuery(TVariableLengthArrayTypesUsedQuery()))
36+
}
37+
2038
Query valueImplicitEnumerationConstantNotUniqueQuery() {
2139
//autogenerate `Query` type
2240
result =

rule_packages/c/Declarations7.json

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,25 @@
11
{
22
"MISRA-C-2012": {
3+
"RULE-18-8": {
4+
"properties": {
5+
"obligation": "required"
6+
},
7+
"queries": [
8+
{
9+
"description": "Using a variable length array can lead to unexpected or undefined program behaviour.",
10+
"kind": "problem",
11+
"name": "Variable-length array types shall not be used",
12+
"precision": "very-high",
13+
"severity": "error",
14+
"short_name": "VariableLengthArrayTypesUsed",
15+
"tags": [
16+
"correctness",
17+
"readability"
18+
]
19+
}
20+
],
21+
"title": "Variable-length array types shall not be used"
22+
},
323
"RULE-8-12": {
424
"properties": {
525
"obligation": "required"

rules.csv

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -726,7 +726,7 @@ c,MISRA-C-2012,RULE-18-4,Yes,Advisory,,,"The +, -, += and -= operators should no
726726
c,MISRA-C-2012,RULE-18-5,Yes,Advisory,,,Declarations should contain no more than two levels of pointer nesting,A5-0-3,Pointers1,Import,
727727
c,MISRA-C-2012,RULE-18-6,Yes,Required,,,The address of an object with automatic storage shall not be copied to another object that persists after the first object has ceased to exist,M7-5-2,Pointers1,Import,
728728
c,MISRA-C-2012,RULE-18-7,Yes,Required,,,Flexible array members shall not be declared,,Declarations,Medium,
729-
c,MISRA-C-2012,RULE-18-8,Yes,Required,,,Variable-length array types shall not be used,,Declarations,Medium,
729+
c,MISRA-C-2012,RULE-18-8,Yes,Required,,,Variable-length array types shall not be used,,Declarations7,Medium,
730730
c,MISRA-C-2012,RULE-19-1,Yes,Mandatory,,,An object shall not be assigned or copied to an overlapping object,M0-2-1,Contracts,Hard,
731731
c,MISRA-C-2012,RULE-19-2,Yes,Advisory,,,The union keyword should not be used,A9-5-1,Banned,Import,
732732
c,MISRA-C-2012,RULE-20-1,Yes,Advisory,,,#include directives should only be preceded by preprocessor directives or comments,M16-0-1,Preprocessor1,Import,

0 commit comments

Comments
 (0)