Skip to content

Commit dda49f7

Browse files
committed
Declarations2: add rule DCL40-C
1 parent 2555c70 commit dda49f7

24 files changed

+344
-35
lines changed
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# DCL40-C: External identifiers shall be distinct
2+
3+
This query implements the CERT-C rule DCL40-C:
4+
5+
> Do not create incompatible declarations of the same function or object
6+
7+
8+
## CERT
9+
10+
** REPLACE THIS BY RUNNING THE SCRIPT `scripts/help/cert-help-extraction.py` **
11+
12+
## Implementation notes
13+
14+
This query considers the first 31 characters of identifiers as significant, as per C99 and reports the case when names are longer than 31 characters and differ in those characters past the 31 first only. This query does not consider universal or extended source characters.
15+
16+
## References
17+
18+
* CERT-C: [DCL40-C: Do not create incompatible declarations of the same function or object](https://wiki.sei.cmu.edu/confluence/display/c)
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/**
2+
* @id c/cert/excess-length-names-identifiers-not-distinct
3+
* @name DCL40-C: External identifiers shall be distinct
4+
* @description Using nondistinct external identifiers results in undefined behaviour.
5+
* @kind problem
6+
* @precision very-high
7+
* @problem.severity warning
8+
* @tags external/cert/id/dcl40-c
9+
* correctness
10+
* maintainability
11+
* readability
12+
* external/cert/obligation/rule
13+
*/
14+
15+
import cpp
16+
import codingstandards.c.cert
17+
import codingstandards.cpp.rules.notdistinctidentifier.NotDistinctIdentifier
18+
19+
class ExcessLengthNamesIdentifiersNotDistinctQuery extends NotDistinctIdentifierSharedQuery {
20+
ExcessLengthNamesIdentifiersNotDistinctQuery() {
21+
this = Declarations2Package::excessLengthNamesIdentifiersNotDistinctQuery()
22+
}
23+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import cpp
2+
import codingstandards.cpp.Linkage
3+
4+
class ExternalIdentifiers extends Declaration {
5+
ExternalIdentifiers() {
6+
hasExternalLinkage(this) and
7+
getNamespace() instanceof GlobalNamespace and
8+
not this.isFromTemplateInstantiation(_) and
9+
not this.isFromUninstantiatedTemplate(_) and
10+
not this.hasDeclaringType() and
11+
not this instanceof UserType and
12+
not this instanceof Operator and
13+
not this.hasName("main")
14+
}
15+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# DCL40-C: Do not create incompatible declarations of the same function or object
2+
3+
This query implements the CERT-C rule DCL40-C:
4+
5+
> Do not create incompatible declarations of the same function or object
6+
## CERT
7+
8+
** REPLACE THIS BY RUNNING THE SCRIPT `scripts/help/cert-help-extraction.py` **
9+
10+
## Implementation notes
11+
12+
None
13+
14+
## References
15+
16+
* CERT-C: [DCL40-C: Do not create incompatible declarations of the same function or object](https://wiki.sei.cmu.edu/confluence/display/c)
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/**
2+
* @id c/cert/incompatible-function-declarations
3+
* @name DCL40-C: Do not create incompatible declarations of the same function or object
4+
* @description Declaring incompatible functions, in other words same named function of different
5+
* return types or with different numbers of parameters or parameter types, then
6+
* accessing those functions can lead to undefined behaviour.
7+
* @kind problem
8+
* @precision high
9+
* @problem.severity error
10+
* @tags external/cert/id/dcl40-c
11+
* correctness
12+
* maintainability
13+
* readability
14+
* external/cert/obligation/rule
15+
*/
16+
17+
import cpp
18+
import codingstandards.c.cert
19+
import ExternalIdentifiers
20+
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+
34+
from ExternalIdentifiers d, FunctionDeclarationEntry f1, FunctionDeclarationEntry f2
35+
where
36+
not isExcluded(f1, Declarations2Package::incompatibleFunctionDeclarationsQuery()) and
37+
not isExcluded(f2, Declarations2Package::incompatibleFunctionDeclarationsQuery()) and
38+
f1 = d.getADeclarationEntry() and
39+
f2 = d.getADeclarationEntry() and
40+
not f1 = f2 and
41+
f1.getLocation().getStartLine() >= f2.getLocation().getStartLine() and
42+
f1.getName() = f2.getName() and
43+
checkMatchingFunction(f1, f2)
44+
select f1, "The object $@ is not compatible with re-declaration $@", f1, f1.getName(), f2,
45+
f2.getName()
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# DCL40-C: Do not create incompatible declarations of the same function or object
2+
3+
This query implements the CERT-C rule DCL40-C:
4+
5+
> Do not create incompatible declarations of the same function or object
6+
7+
8+
## CERT
9+
10+
** REPLACE THIS BY RUNNING THE SCRIPT `scripts/help/cert-help-extraction.py` **
11+
12+
## Implementation notes
13+
14+
None
15+
16+
## References
17+
18+
* CERT-C: [DCL40-C: Do not create incompatible declarations of the same function or object](https://wiki.sei.cmu.edu/confluence/display/c)
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/**
2+
* @id c/cert/incompatible-object-declarations
3+
* @name DCL40-C: Do not create incompatible declarations of the same function or object
4+
* @description Declaring incompatible objects, in other words same named objects of different
5+
* types, then accessing those objects can lead to undefined behaviour.
6+
* @kind problem
7+
* @precision high
8+
* @problem.severity error
9+
* @tags external/cert/id/dcl40-c
10+
* correctness
11+
* maintainability
12+
* readability
13+
* external/cert/obligation/rule
14+
*/
15+
16+
import cpp
17+
import codingstandards.c.cert
18+
import ExternalIdentifiers
19+
20+
from VariableDeclarationEntry decl1, VariableDeclarationEntry decl2
21+
where
22+
not isExcluded(decl1, Declarations2Package::incompatibleObjectDeclarationsQuery()) and
23+
not isExcluded(decl2, Declarations2Package::incompatibleObjectDeclarationsQuery()) and
24+
not decl1.getUnspecifiedType() = decl2.getUnspecifiedType() and
25+
decl1.getDeclaration() instanceof ExternalIdentifiers and
26+
decl2.getDeclaration() instanceof ExternalIdentifiers and
27+
decl1.getLocation().getStartLine() >= decl2.getLocation().getStartLine() and
28+
decl1.getVariable().getName() = decl2.getVariable().getName()
29+
select decl1, "The object $@ is not compatible with re-declaration $@", decl1, decl1.getName(),
30+
decl2, decl2.getName()
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
c/common/test/rules/notdistinctidentifier/NotDistinctIdentifier.ql
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
| test1.c:4:12:4:12 | declaration of f | The object $@ is not compatible with re-declaration $@ | test1.c:4:12:4:12 | declaration of f | f | test.c:4:6:4:6 | definition of f | f |
2+
| test.c:4:6:4:6 | definition of f | The object $@ is not compatible with re-declaration $@ | test.c:4:6:4:6 | definition of f | f | test1.c:4:12:4:12 | declaration of f | f |
3+
| test.c:8:6:8:7 | declaration of f1 | The object $@ is not compatible with re-declaration $@ | test.c:8:6:8:7 | declaration of f1 | f1 | test1.c:5:13:5:14 | declaration of f1 | f1 |
4+
| test.c:9:6:9:7 | definition of f2 | The object $@ is not compatible with re-declaration $@ | test.c:9:6:9:7 | definition of f2 | f2 | test1.c:6:6:6:7 | definition of f2 | f2 |
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
rules/DCL40-C/IncompatibleFunctionDeclarations.ql
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
| test1.c:2:12:2:12 | declaration of i | The object $@ is not compatible with re-declaration $@ | test1.c:2:12:2:12 | declaration of i | i | test.c:1:7:1:7 | definition of i | i |
2+
| test.c:2:5:2:5 | definition of a | The object $@ is not compatible with re-declaration $@ | test.c:2:5:2:5 | definition of a | a | test1.c:1:13:1:13 | declaration of a | a |
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
rules/DCL40-C/IncompatibleObjectDeclarations.ql

c/cert/test/rules/DCL40-C/test.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
short i; // NON_COMPLIANT
2+
int a[] = {1, 2, 3, 4}; // NON_COMPLIANT
3+
4+
long f(int a) { // NON_COMPLIANT
5+
return a * 2;
6+
}
7+
8+
void f1(long a); // NON_COMPLIANT
9+
void f2() {} // NON_COMPLIANT
10+
int f3(); // COMPLIANT

c/cert/test/rules/DCL40-C/test1.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
extern int *a; // NON_COMPLIANT
2+
extern int i; // NON_COMPLIANT
3+
4+
extern int f(int a); // NON_COMPLIANT
5+
extern void f1(int a); // NON_COMPLIANT
6+
void f2(int a, ...) {} // NON_COMPLIANT
7+
int f3(); // COMPLIANT
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
// GENERATED FILE - DO NOT MODIFY
2+
import codingstandards.cpp.rules.notdistinctidentifier.NotDistinctIdentifier

c/misra/test/rules/RULE-5-1/ExternalIdentifiersNotDistinct.qlref

Lines changed: 0 additions & 1 deletion
This file was deleted.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
c/common/test/rules/notdistinctidentifier/NotDistinctIdentifier.ql

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

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ import codingstandards.cpp.exclusions.RuleMetadata
55

66
newtype Declarations2Query =
77
TDeclaringAFlexibleArrayMemberQuery() or
8+
TExcessLengthNamesIdentifiersNotDistinctQuery() or
9+
TIncompatibleObjectDeclarationsQuery() or
10+
TIncompatibleFunctionDeclarationsQuery() or
811
TVariablesInsideSwitchStatementQuery()
912

1013
predicate isDeclarations2QueryMetadata(Query query, string queryId, string ruleId) {
@@ -16,6 +19,30 @@ predicate isDeclarations2QueryMetadata(Query query, string queryId, string ruleI
1619
"c/cert/declaring-a-flexible-array-member" and
1720
ruleId = "DCL38-C"
1821
or
22+
query =
23+
// `Query` instance for the `excessLengthNamesIdentifiersNotDistinct` query
24+
Declarations2Package::excessLengthNamesIdentifiersNotDistinctQuery() and
25+
queryId =
26+
// `@id` for the `excessLengthNamesIdentifiersNotDistinct` query
27+
"c/cert/excess-length-names-identifiers-not-distinct" and
28+
ruleId = "DCL40-C"
29+
or
30+
query =
31+
// `Query` instance for the `incompatibleObjectDeclarations` query
32+
Declarations2Package::incompatibleObjectDeclarationsQuery() and
33+
queryId =
34+
// `@id` for the `incompatibleObjectDeclarations` query
35+
"c/cert/incompatible-object-declarations" and
36+
ruleId = "DCL40-C"
37+
or
38+
query =
39+
// `Query` instance for the `incompatibleFunctionDeclarations` query
40+
Declarations2Package::incompatibleFunctionDeclarationsQuery() and
41+
queryId =
42+
// `@id` for the `incompatibleFunctionDeclarations` query
43+
"c/cert/incompatible-function-declarations" and
44+
ruleId = "DCL40-C"
45+
or
1946
query =
2047
// `Query` instance for the `variablesInsideSwitchStatement` query
2148
Declarations2Package::variablesInsideSwitchStatementQuery() and
@@ -33,6 +60,27 @@ module Declarations2Package {
3360
TQueryC(TDeclarations2PackageQuery(TDeclaringAFlexibleArrayMemberQuery()))
3461
}
3562

63+
Query excessLengthNamesIdentifiersNotDistinctQuery() {
64+
//autogenerate `Query` type
65+
result =
66+
// `Query` type for `excessLengthNamesIdentifiersNotDistinct` query
67+
TQueryC(TDeclarations2PackageQuery(TExcessLengthNamesIdentifiersNotDistinctQuery()))
68+
}
69+
70+
Query incompatibleObjectDeclarationsQuery() {
71+
//autogenerate `Query` type
72+
result =
73+
// `Query` type for `incompatibleObjectDeclarations` query
74+
TQueryC(TDeclarations2PackageQuery(TIncompatibleObjectDeclarationsQuery()))
75+
}
76+
77+
Query incompatibleFunctionDeclarationsQuery() {
78+
//autogenerate `Query` type
79+
result =
80+
// `Query` type for `incompatibleFunctionDeclarations` query
81+
TQueryC(TDeclarations2PackageQuery(TIncompatibleFunctionDeclarationsQuery()))
82+
}
83+
3684
Query variablesInsideSwitchStatementQuery() {
3785
//autogenerate `Query` type
3886
result =
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
/**
2+
* Provides a library which includes a `problems` predicate for reporting....
3+
*/
4+
5+
import cpp
6+
import codingstandards.cpp.Customizations
7+
import codingstandards.cpp.Exclusions
8+
9+
abstract class NotDistinctIdentifierSharedQuery extends Query { }
10+
11+
Query getQuery() { result instanceof NotDistinctIdentifierSharedQuery }
12+
13+
query predicate problems(Element e, string message) {
14+
not isExcluded(e, getQuery()) and message = "<replace with problem alert message for >"
15+
}

rule_packages/c/Declarations1.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@
8686
"precision": "very-high",
8787
"severity": "warning",
8888
"short_name": "ExternalIdentifiersNotDistinct",
89+
"shared_implementation_short_name": "NotDistinctIdentifier",
8990
"tags": [
9091
"correctness",
9192
"maintainability",

0 commit comments

Comments
 (0)