Skip to content

Commit 791526e

Browse files
Address next round of feedback
1 parent ef76126 commit 791526e

File tree

6 files changed

+75
-10
lines changed

6 files changed

+75
-10
lines changed

c/misra/src/rules/RULE-18-10/PointersToVariablyModifiedArrayTypesUsed.ql

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,9 @@ where
4242
if v.getType().(PointerType).getBaseType() instanceof CandidateVlaType
4343
then relationstr = "pointer to"
4444
else relationstr = "with inner"
45-
)
45+
) and
46+
// Remove results that appear to be unreliable, potentially from a macro.
47+
not v.appearsDuplicated()
4648
select v,
4749
declstr + v.getName() + " is " + adjuststr + " variably-modified type, " + relationstr +
4850
" variable length array of non constant size $@ and element type '" +

c/misra/src/rules/RULE-18-8/VariableLengthArrayTypesUsed.ql

Lines changed: 43 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,55 @@
1515
import cpp
1616
import codingstandards.c.misra
1717

18-
from VlaDeclStmt v, Expr size, ArrayType arrayType, string typeStr
18+
/**
19+
* Typedefs may be declared as VLAs, eg, `typedef int vla[x];`. This query finds types that refer to
20+
* such typedef types, for instance `vla foo;` or adding a dimension via `vla bar[10];`.
21+
*
22+
* Consts and other specifiers may be added, but `vla *ptr;` is not a VLA any more, and is excluded.
23+
*/
24+
class VlaTypedefType extends Type {
25+
VlaDeclStmt vlaDecl;
26+
ArrayType arrayType;
27+
28+
VlaTypedefType() {
29+
// Holds for direct references to the typedef type:
30+
this = vlaDecl.getType() and
31+
vlaDecl.getType() instanceof TypedefType and
32+
arrayType = vlaDecl.getType().stripTopLevelSpecifiers()
33+
or
34+
// Holds for adding a constant dimension to a VLA typedef type:
35+
arrayType = this.stripTopLevelSpecifiers() and
36+
vlaDecl = arrayType.getBaseType().(VlaTypedefType).getVlaDeclStmt()
37+
or
38+
// Carefully ignore specifiers, `stripTopLevelSpecifiers()` resolves past the typedef
39+
exists(SpecifiedType st, VlaTypedefType inner |
40+
st = this and
41+
st.getBaseType() = inner and
42+
arrayType = inner.getArrayType() and
43+
vlaDecl = inner.getVlaDeclStmt()
44+
)
45+
}
46+
47+
VlaDeclStmt getVlaDeclStmt() { result = vlaDecl }
48+
49+
ArrayType getArrayType() { result = arrayType }
50+
}
51+
52+
from Variable v, Expr size, ArrayType arrayType, VlaDeclStmt vlaDecl, string typeStr
1953
where
2054
not isExcluded(v, Declarations7Package::variableLengthArrayTypesUsedQuery()) and
21-
size = v.getVlaDimensionStmt(0).getDimensionExpr() and
55+
size = vlaDecl.getVlaDimensionStmt(0).getDimensionExpr() and
2256
(
2357
// Holds is if v is a variable declaration:
24-
arrayType = v.getVariable().getType().stripTopLevelSpecifiers()
58+
v = vlaDecl.getVariable() and
59+
arrayType = v.getType().stripTopLevelSpecifiers()
2560
or
2661
// Holds is if v is a typedef declaration:
27-
arrayType = v.getType().stripTopLevelSpecifiers()
62+
exists(VlaTypedefType typedef |
63+
v.getType() = typedef and
64+
arrayType = typedef.getArrayType() and
65+
vlaDecl = typedef.getVlaDeclStmt()
66+
)
2867
) and
2968
typeStr = arrayType.getBaseType().toString()
3069
select v, "Variable length array of element type '" + typeStr + "' with non-constant size $@.",

c/misra/src/rules/RULE-18-9/ArrayToPointerConversionOfTemporaryObject.ql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,5 +66,5 @@ where
6666
fa.getTemporary() = temporary and
6767
conversion.getExpr() = fa and
6868
isUsedOrStored(temporaryObjectFlowStep*(conversion.getExpr()))
69-
select conversion, "Array to pointer conversion of array $@ from temporary object $@",
69+
select conversion, "Array to pointer conversion of array $@ from temporary object $@.",
7070
fa.getTarget(), fa.getTarget().getName(), temporary, temporary.toString()

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

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,4 +92,14 @@ void f2(int (*p1)[3], // COMPLIANT
9292
int (*p3)[2][*], // NON-COMPLIANT[FALSE_NEGATIVE]
9393
int (*p4)[*][2], // NON-COMPLIANT[FALSE_NEGATIVE]
9494
int (*p5)[*][*] // NON-COMPLIANT[FALSE_NEGATIVE]
95-
);
95+
);
96+
97+
#define CONFUSING_MACRO() \
98+
int x; \
99+
int (*vla)[x]; \
100+
int (*not_vla)[];
101+
102+
void f3() {
103+
// We cannot report `vla` in this macro without a false positive for `not_vla`.
104+
CONFUSING_MACRO() // COMPLIANT
105+
}

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

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,13 @@ void f(int n) {
1414

1515
extern int e1[]; // COMPLIANT
1616

17-
// A typedef is not a VLA. However, `VlaDeclStmt`s match the typedef.
18-
typedef int vlaTypedef[n]; // COMPLIANT[FALSE_POSITIVE]
19-
vlaTypedef t1; // NON_COMPLIANT[FALSE_NEGATIVE]
17+
// A typedef is not a VLA.
18+
typedef int vlaTypedef[n]; // COMPLIANT
19+
// The declarations using the typedef may or may not be VLAs.
20+
vlaTypedef t1; // NON_COMPLIANT
21+
vlaTypedef t2[1]; // NON_COMPLIANT
22+
vlaTypedef t3[x]; // NON_COMPLIANT
23+
vlaTypedef *t4; // COMPLIANT
2024
}
2125

2226
void f1(int n,

cpp/common/src/codingstandards/cpp/VariablyModifiedTypes.qll

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ import cpp
22

33
/**
44
* A declaration involving a variably-modified type.
5+
*
6+
* Note, this holds for both VLA variable and VLA typedefs.
57
*/
68
class VmtDeclarationEntry extends DeclarationEntry {
79
Expr sizeExpr;
@@ -28,6 +30,14 @@ class VmtDeclarationEntry extends DeclarationEntry {
2830
Expr getSizeExpr() { result = sizeExpr }
2931

3032
CandidateVlaType getVlaType() { result = vlaType }
33+
34+
/* VLAs may occur in macros, and result in duplication that messes up our analysis. */
35+
predicate appearsDuplicated() {
36+
exists(VmtDeclarationEntry other |
37+
other != this and
38+
other.getSizeExpr() = getSizeExpr()
39+
)
40+
}
3141
}
3242

3343
/**

0 commit comments

Comments
 (0)