Skip to content

Commit 7eaad20

Browse files
committed
Compatible types: performance improvements
Modify the `Compatible.qll` library to improve performance by restricting to function declarations for the same function. Adopt the Compatible library in DCL40-C, which has also improved detection of compatible types.
1 parent 18a3f35 commit 7eaad20

File tree

3 files changed

+25
-17
lines changed

3 files changed

+25
-17
lines changed

c/cert/src/rules/DCL40-C/IncompatibleFunctionDeclarations.ql

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -16,30 +16,32 @@
1616

1717
import cpp
1818
import codingstandards.c.cert
19+
import codingstandards.cpp.Compatible
1920
import ExternalIdentifiers
2021

21-
//checks if they are incompatible based on return type, number of parameters and parameter types
22-
predicate checkMatchingFunction(FunctionDeclarationEntry d, FunctionDeclarationEntry d2) {
23-
not d.getType() = d2.getType()
24-
or
25-
not d.getNumberOfParameters() = d2.getNumberOfParameters()
26-
or
27-
exists(ParameterDeclarationEntry p, ParameterDeclarationEntry p2, int i |
28-
d.getParameterDeclarationEntry(i) = p and
29-
d2.getParameterDeclarationEntry(i) = p2 and
30-
not p.getType() = p2.getType()
31-
)
32-
}
33-
3422
from ExternalIdentifiers d, FunctionDeclarationEntry f1, FunctionDeclarationEntry f2
3523
where
3624
not isExcluded(f1, Declarations2Package::incompatibleFunctionDeclarationsQuery()) and
3725
not isExcluded(f2, Declarations2Package::incompatibleFunctionDeclarationsQuery()) and
38-
f1 = d.getADeclarationEntry() and
39-
f2 = d.getADeclarationEntry() and
4026
not f1 = f2 and
41-
f1.getLocation().getStartLine() >= f2.getLocation().getStartLine() and
27+
f1.getDeclaration() = d and
28+
f2.getDeclaration() = d and
4229
f1.getName() = f2.getName() and
43-
checkMatchingFunction(f1, f2)
30+
(
31+
//return type check
32+
not typesCompatible(f1.getType(), f2.getType())
33+
or
34+
//parameter type check
35+
parameterTypesIncompatible(f1, f2)
36+
or
37+
not f1.getNumberOfParameters() = f2.getNumberOfParameters()
38+
) and
39+
// Apply ordering on start line, trying to avoid the optimiser applying this join too early
40+
// in the pipeline
41+
exists(int f1Line, int f2Line |
42+
f1.getLocation().hasLocationInfo(_, f1Line, _, _, _) and
43+
f2.getLocation().hasLocationInfo(_, f2Line, _, _, _) and
44+
f1Line >= f2Line
45+
)
4446
select f1, "The object $@ is not compatible with re-declaration $@", f1, f1.getName(), f2,
4547
f2.getName()
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
- `DCL40-C` - `IncompatibleFunctionDeclarations.ql`:
2+
- Reduce false positives by identifying compatible integer arithmetic types (e.g. "signed int" and "int").

cpp/common/src/codingstandards/cpp/Compatible.qll

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import cpp
22

3+
pragma[noinline]
4+
pragma[nomagic]
35
predicate typesCompatible(Type t1, Type t2) {
46
t1 = t2
57
or
@@ -8,6 +10,7 @@ predicate typesCompatible(Type t1, Type t2) {
810
}
911

1012
predicate parameterTypesIncompatible(FunctionDeclarationEntry f1, FunctionDeclarationEntry f2) {
13+
f1.getDeclaration() = f2.getDeclaration() and
1114
exists(ParameterDeclarationEntry p1, ParameterDeclarationEntry p2, int i |
1215
p1 = f1.getParameterDeclarationEntry(i) and
1316
p2 = f2.getParameterDeclarationEntry(i)
@@ -17,6 +20,7 @@ predicate parameterTypesIncompatible(FunctionDeclarationEntry f1, FunctionDeclar
1720
}
1821

1922
predicate parameterNamesIncompatible(FunctionDeclarationEntry f1, FunctionDeclarationEntry f2) {
23+
f1.getDeclaration() = f2.getDeclaration() and
2024
exists(ParameterDeclarationEntry p1, ParameterDeclarationEntry p2, int i |
2125
p1 = f1.getParameterDeclarationEntry(i) and
2226
p2 = f2.getParameterDeclarationEntry(i)

0 commit comments

Comments
 (0)