Skip to content

Commit 3b4443e

Browse files
committed
Declarations4: add RULE-8-4
1 parent b601c91 commit 3b4443e

16 files changed

+213
-19
lines changed

c/misra/src/rules/RULE-8-3/DeclarationsOfAFunctionSameNameAndType.ql

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -15,24 +15,6 @@ import cpp
1515
import codingstandards.c.misra
1616
import codingstandards.cpp.Compatible
1717

18-
predicate parameterTypesIncompatible(FunctionDeclarationEntry f1, FunctionDeclarationEntry f2) {
19-
exists(ParameterDeclarationEntry p1, ParameterDeclarationEntry p2, int i |
20-
p1 = f1.getParameterDeclarationEntry(i) and
21-
p2 = f2.getParameterDeclarationEntry(i)
22-
|
23-
not typesCompatible(p1.getType(), p2.getType())
24-
)
25-
}
26-
27-
predicate parameterNamesIncompatible(FunctionDeclarationEntry f1, FunctionDeclarationEntry f2) {
28-
exists(ParameterDeclarationEntry p1, ParameterDeclarationEntry p2, int i |
29-
p1 = f1.getParameterDeclarationEntry(i) and
30-
p2 = f2.getParameterDeclarationEntry(i)
31-
|
32-
not p1.getName() = p2.getName()
33-
)
34-
}
35-
3618
from FunctionDeclarationEntry f1, FunctionDeclarationEntry f2, string case
3719
where
3820
not isExcluded(f1, Declarations4Package::declarationsOfAFunctionSameNameAndTypeQuery()) and
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/**
2+
* @id c/misra/compatible-declaration-function-defined
3+
* @name RULE-8-4: A compatible declaration shall be visible when a function with external linkage is defined
4+
* @description A compatible declaration shall be visible when a function with external linkage is
5+
* defined, otherwise program behaviour may be undefined.
6+
* @kind problem
7+
* @precision very-high
8+
* @problem.severity error
9+
* @tags external/misra/id/rule-8-4
10+
* readability
11+
* maintainability
12+
* correctness
13+
* external/misra/obligation/required
14+
*/
15+
16+
import cpp
17+
import codingstandards.c.misra
18+
import codingstandards.cpp.Identifiers
19+
import codingstandards.cpp.Compatible
20+
21+
from FunctionDeclarationEntry f1
22+
where
23+
not isExcluded(f1, Declarations4Package::compatibleDeclarationFunctionDefinedQuery()) and
24+
f1.isDefinition() and
25+
f1.getDeclaration() instanceof ExternalIdentifiers and
26+
//no declaration matches exactly
27+
(
28+
not exists(FunctionDeclarationEntry f2 |
29+
not f2.isDefinition() and
30+
f2.getDeclaration() = f1.getDeclaration()
31+
)
32+
or
33+
//or one exists that is close but incompatible in some way
34+
exists(FunctionDeclarationEntry f2 |
35+
f1.getName() = f2.getName() and
36+
not f2.isDefinition() and
37+
f2.getDeclaration() = f1.getDeclaration() and
38+
//return types differ
39+
(
40+
not typesCompatible(f1.getType(), f2.getType())
41+
or
42+
//parameter types differ
43+
parameterTypesIncompatible(f1, f2)
44+
or
45+
//parameter names differ
46+
parameterNamesIncompatible(f1, f2)
47+
)
48+
)
49+
)
50+
select f1, "No separate compatible declaration found for this definition."
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/**
2+
* @id c/misra/compatible-declaration-object-defined
3+
* @name RULE-8-4: A compatible declaration shall be visible when an object with external linkage is defined
4+
* @description A compatible declaration shall be visible when an object with external linkage is
5+
* defined, otherwise program behaviour may be undefined.
6+
* @kind problem
7+
* @precision very-high
8+
* @problem.severity error
9+
* @tags external/misra/id/rule-8-4
10+
* readability
11+
* maintainability
12+
* correctness
13+
* external/misra/obligation/required
14+
*/
15+
16+
import cpp
17+
import codingstandards.c.misra
18+
import codingstandards.cpp.Identifiers
19+
import codingstandards.cpp.Compatible
20+
21+
from VariableDeclarationEntry decl1
22+
where
23+
not isExcluded(decl1, Declarations4Package::compatibleDeclarationObjectDefinedQuery()) and
24+
decl1.isDefinition() and
25+
decl1.getDeclaration() instanceof ExternalIdentifiers and
26+
(
27+
//no declaration matches exactly
28+
not exists(VariableDeclarationEntry decl2 |
29+
not decl2.isDefinition() and decl2.getDeclaration() = decl1.getDeclaration()
30+
) and
31+
//and none is close enough
32+
not exists(VariableDeclarationEntry decl2 |
33+
not decl2.isDefinition() and
34+
decl1.getVariable().getQualifiedName() = decl2.getVariable().getQualifiedName() and
35+
typesCompatible(decl1.getType(), decl2.getType())
36+
)
37+
)
38+
select decl1, "No separate compatible declaration found for this definition."
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
| function2.c:5:6:5:7 | definition of f3 | |
2+
| function2.c:7:6:7:7 | definition of f4 | |
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
rules/RULE-8-4/CompatibleDeclarationFunctionDefined.ql
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
| object1.c:4:12:4:13 | definition of i1 | No separate compatible declaration found for this definition. |
2+
| object1.c:6:5:6:6 | definition of i2 | No separate compatible declaration found for this definition. |
3+
| object2.c:1:7:1:8 | definition of i3 | No separate compatible declaration found for this definition. |
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
rules/RULE-8-4/CompatibleDeclarationObjectDefined.ql
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
extern void f1(); // COMPLIANT
2+
extern void f2(int x, int y); // COMPLIANT
3+
extern void f3(int x, int y); // NON_COMPLIANT
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
void f1() {} // COMPLIANT
2+
3+
void f2(int x, int y) {} // COMPLIANT
4+
5+
void f3(short x, int y) {} // NON_COMPLIANT
6+
7+
void f4() {} // NON_COMPLIANT
8+
9+
static void f5() {} // COMPLIANT

c/misra/test/rules/RULE-8-4/object1.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
extern int i;
2+
i = 0; // COMPLIANT
3+
4+
extern int i1 = 0; // NON_COMPLIANT
5+
6+
int i2 = 0; // NON_COMPLIANT
7+
8+
extern int i3; // NON_COMPLIANT
9+
10+
extern int i4; // COMPLIANT

c/misra/test/rules/RULE-8-4/object2.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
short i3 = 0; // NON_COMPLIANT
2+
3+
signed int i4 = 0; // COMPLIANT

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

Whitespace-only changes.

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

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,21 @@ predicate typesCompatible(Type t1, Type t2) {
66
//signed int is same as int ect
77
t1.(IntegralType).getCanonicalArithmeticType() = t2.(IntegralType).getCanonicalArithmeticType()
88
}
9+
10+
predicate parameterTypesIncompatible(FunctionDeclarationEntry f1, FunctionDeclarationEntry f2) {
11+
exists(ParameterDeclarationEntry p1, ParameterDeclarationEntry p2, int i |
12+
p1 = f1.getParameterDeclarationEntry(i) and
13+
p2 = f2.getParameterDeclarationEntry(i)
14+
|
15+
not typesCompatible(p1.getType(), p2.getType())
16+
)
17+
}
18+
19+
predicate parameterNamesIncompatible(FunctionDeclarationEntry f1, FunctionDeclarationEntry f2) {
20+
exists(ParameterDeclarationEntry p1, ParameterDeclarationEntry p2, int i |
21+
p1 = f1.getParameterDeclarationEntry(i) and
22+
p2 = f2.getParameterDeclarationEntry(i)
23+
|
24+
not p1.getName() = p2.getName()
25+
)
26+
}

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

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ newtype Declarations4Query =
77
TFunctionTypesNotInPrototypeFormQuery() or
88
TDeclarationsOfAnObjectSameNameAndTypeQuery() or
99
TDeclarationsOfAFunctionSameNameAndTypeQuery() or
10+
TCompatibleDeclarationObjectDefinedQuery() or
11+
TCompatibleDeclarationFunctionDefinedQuery() or
1012
TIdentifierWithExternalLinkageOneDefinitionQuery()
1113

1214
predicate isDeclarations4QueryMetadata(Query query, string queryId, string ruleId) {
@@ -34,6 +36,22 @@ predicate isDeclarations4QueryMetadata(Query query, string queryId, string ruleI
3436
"c/misra/declarations-of-a-function-same-name-and-type" and
3537
ruleId = "RULE-8-3"
3638
or
39+
query =
40+
// `Query` instance for the `compatibleDeclarationObjectDefined` query
41+
Declarations4Package::compatibleDeclarationObjectDefinedQuery() and
42+
queryId =
43+
// `@id` for the `compatibleDeclarationObjectDefined` query
44+
"c/misra/compatible-declaration-object-defined" and
45+
ruleId = "RULE-8-4"
46+
or
47+
query =
48+
// `Query` instance for the `compatibleDeclarationFunctionDefined` query
49+
Declarations4Package::compatibleDeclarationFunctionDefinedQuery() and
50+
queryId =
51+
// `@id` for the `compatibleDeclarationFunctionDefined` query
52+
"c/misra/compatible-declaration-function-defined" and
53+
ruleId = "RULE-8-4"
54+
or
3755
query =
3856
// `Query` instance for the `identifierWithExternalLinkageOneDefinition` query
3957
Declarations4Package::identifierWithExternalLinkageOneDefinitionQuery() and
@@ -65,6 +83,20 @@ module Declarations4Package {
6583
TQueryC(TDeclarations4PackageQuery(TDeclarationsOfAFunctionSameNameAndTypeQuery()))
6684
}
6785

86+
Query compatibleDeclarationObjectDefinedQuery() {
87+
//autogenerate `Query` type
88+
result =
89+
// `Query` type for `compatibleDeclarationObjectDefined` query
90+
TQueryC(TDeclarations4PackageQuery(TCompatibleDeclarationObjectDefinedQuery()))
91+
}
92+
93+
Query compatibleDeclarationFunctionDefinedQuery() {
94+
//autogenerate `Query` type
95+
result =
96+
// `Query` type for `compatibleDeclarationFunctionDefined` query
97+
TQueryC(TDeclarations4PackageQuery(TCompatibleDeclarationFunctionDefinedQuery()))
98+
}
99+
68100
Query identifierWithExternalLinkageOneDefinitionQuery() {
69101
//autogenerate `Query` type
70102
result =

rule_packages/c/Declarations4.json

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,48 @@
5353
],
5454
"title": "All declarations of an object or function shall use the same names and type qualifiers"
5555
},
56+
"RULE-8-4": {
57+
"properties": {
58+
"obligation": "required"
59+
},
60+
"queries": [
61+
{
62+
"description": "A compatible declaration shall be visible when an object with external linkage is defined, otherwise program behaviour may be undefined.",
63+
"kind": "problem",
64+
"name": "A compatible declaration shall be visible when an object with external linkage is defined",
65+
"precision": "very-high",
66+
"severity": "error",
67+
"short_name": "CompatibleDeclarationObjectDefined",
68+
"tags": [
69+
"readability",
70+
"maintainability",
71+
"correctness"
72+
],
73+
"implementation_scope": {
74+
"description": "This query does not check for the recommendation of declarations in headers.",
75+
"items": []
76+
}
77+
},
78+
{
79+
"description": "A compatible declaration shall be visible when a function with external linkage is defined, otherwise program behaviour may be undefined.",
80+
"kind": "problem",
81+
"name": "A compatible declaration shall be visible when a function with external linkage is defined",
82+
"precision": "very-high",
83+
"severity": "error",
84+
"short_name": "CompatibleDeclarationFunctionDefined",
85+
"tags": [
86+
"readability",
87+
"maintainability",
88+
"correctness"
89+
],
90+
"implementation_scope": {
91+
"description": "This query does not check for the recommendation of declarations in headers.",
92+
"items": []
93+
}
94+
}
95+
],
96+
"title": "A compatible declaration shall be visible when an object or function with external linkage is defined"
97+
},
5698
"RULE-8-6": {
5799
"properties": {
58100
"obligation": "required"

rules.csv

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -649,7 +649,7 @@ c,MISRA-C-2012,RULE-7-4,Yes,Required,,,A string literal shall not be assigned to
649649
c,MISRA-C-2012,RULE-8-1,Yes,Required,,,Types shall be explicitly specified,,Declarations3,Medium,
650650
c,MISRA-C-2012,RULE-8-2,Yes,Required,,,Function types shall be in prototype form with named parameters,,Declarations4,Medium,
651651
c,MISRA-C-2012,RULE-8-3,Yes,Required,,,All declarations of an object or function shall use the same names and type qualifiers,M3-2-1,Declarations4,Medium,
652-
c,MISRA-C-2012,RULE-8-4,Yes,Required,,,A compatible declaration shall be visible when an object or function with external linkage is defined,,Declarations,Medium,
652+
c,MISRA-C-2012,RULE-8-4,Yes,Required,,,A compatible declaration shall be visible when an object or function with external linkage is defined,,Declarations4,Medium,
653653
c,MISRA-C-2012,RULE-8-5,Yes,Required,,,An external object or function shall be declared once in one and only one file,,Declarations,Medium,
654654
c,MISRA-C-2012,RULE-8-6,Yes,Required,,,An identifier with external linkage shall have exactly one external definition,M3-2-4,Declarations4,Import,
655655
c,MISRA-C-2012,RULE-8-7,Yes,Advisory,,,Functions and objects should not be defined with external linkage if they are referenced in only one translation unit,,Declarations,Medium,

0 commit comments

Comments
 (0)