Skip to content

Commit e5fdac4

Browse files
authored
Merge pull request #157 from knewbury01/knewbury01/Declarations6
Implement C Declarations6 package
2 parents e37a13c + 1e8eb59 commit e5fdac4

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+646
-34
lines changed

.vscode/tasks.json

+1
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,7 @@
209209
"Declarations3",
210210
"Declarations4",
211211
"Declarations5",
212+
"Declarations6",
212213
"Exceptions1",
213214
"Exceptions2",
214215
"Expressions",

c/cert/src/rules/DCL38-C/DeclaringAFlexibleArrayMember.ql

+2-19
Original file line numberDiff line numberDiff line change
@@ -15,29 +15,12 @@
1515

1616
import cpp
1717
import codingstandards.c.cert
18-
19-
/**
20-
* A member with the type array that is last in a struct
21-
* includes any sized array (either specified or not)
22-
*/
23-
class FlexibleArrayMember extends MemberVariable {
24-
Struct s;
25-
26-
FlexibleArrayMember() {
27-
this.getType() instanceof ArrayType and
28-
this.getDeclaringType() = s and
29-
not exists(int i, int j |
30-
s.getAMember(i) = this and
31-
exists(s.getAMember(j)) and
32-
j > i
33-
)
34-
}
35-
}
18+
import codingstandards.c.Variable
3619

3720
from VariableDeclarationEntry m, ArrayType a
3821
where
3922
not isExcluded(m, Declarations2Package::declaringAFlexibleArrayMemberQuery()) and
4023
m.getType() = a and
41-
m.getVariable() instanceof FlexibleArrayMember and
24+
m.getVariable() instanceof FlexibleArrayMemberCandidate and
4225
a.getArraySize() = 1
4326
select m, "Incorrect syntax used for declaring this flexible array member."

c/common/src/codingstandards/c/Variable.qll

+32
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,35 @@ class VlaVariable extends Variable {
66
/* Extractor workaround do determine if a VLA array has the specifier volatile.*/
77
override predicate isVolatile() { this.getType().(ArrayType).getBaseType().isVolatile() }
88
}
9+
10+
/**
11+
* A flexible array member
12+
* ie member with the type array that is last in a struct
13+
* has no size specified
14+
*/
15+
class FlexibleArrayMember extends FlexibleArrayMemberCandidate {
16+
FlexibleArrayMember() {
17+
exists(ArrayType t |
18+
this.getType() = t and
19+
not exists(t.getSize())
20+
)
21+
}
22+
}
23+
24+
/**
25+
* A member with the type array that is last in a struct
26+
* includes any sized array (either specified or not)
27+
*/
28+
class FlexibleArrayMemberCandidate extends MemberVariable {
29+
Struct s;
30+
31+
FlexibleArrayMemberCandidate() {
32+
this.getType() instanceof ArrayType and
33+
this.getDeclaringType() = s and
34+
not exists(int i, int j |
35+
s.getAMember(i) = this and
36+
exists(s.getAMember(j)) and
37+
j > i
38+
)
39+
}
40+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/**
2+
* @id c/misra/function-declared-implicitly
3+
* @name RULE-17-3: A function shall not be declared implicitly
4+
* @description Omission of type specifiers may not be supported by some compilers. Additionally
5+
* implicit typing can lead to undefined behaviour.
6+
* @kind problem
7+
* @precision very-high
8+
* @problem.severity error
9+
* @tags external/misra/id/rule-17-3
10+
* correctness
11+
* readability
12+
* external/misra/obligation/mandatory
13+
*/
14+
15+
import cpp
16+
import codingstandards.c.misra
17+
import codingstandards.cpp.Identifiers
18+
19+
from FunctionDeclarationEntry fde
20+
where
21+
not isExcluded(fde, Declarations6Package::functionDeclaredImplicitlyQuery()) and
22+
(
23+
//use before declaration
24+
fde.isImplicit()
25+
or
26+
//declared but type not explicit
27+
isDeclaredImplicit(fde.getDeclaration())
28+
)
29+
select fde, "Function declaration is implicit."
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/**
2+
* @id c/misra/flexible-array-members-declared
3+
* @name RULE-18-7: Flexible array members shall not be declared
4+
* @description The use of flexible array members can lead to unexpected program behaviour.
5+
* @kind problem
6+
* @precision very-high
7+
* @problem.severity error
8+
* @tags external/misra/id/rule-18-7
9+
* correctness
10+
* external/misra/obligation/required
11+
*/
12+
13+
import cpp
14+
import codingstandards.c.misra
15+
import codingstandards.c.Variable
16+
17+
from FlexibleArrayMember f
18+
where not isExcluded(f, Declarations6Package::flexibleArrayMembersDeclaredQuery())
19+
select f, "Flexible array member declared."
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/**
2+
* @id c/misra/identifiers-with-external-linkage-not-unique
3+
* @name RULE-5-8: Identifiers that define objects or functions with external linkage shall be unique
4+
* @description Using non-unique identifiers can lead to developer confusion.
5+
* @kind problem
6+
* @precision very-high
7+
* @problem.severity error
8+
* @tags external/misra/id/rule-5-8
9+
* maintainability
10+
* readability
11+
* external/misra/obligation/required
12+
*/
13+
14+
import cpp
15+
import codingstandards.c.misra
16+
import codingstandards.cpp.Identifiers
17+
18+
from Declaration de, ExternalIdentifiers e
19+
where
20+
not isExcluded(de, Declarations6Package::identifiersWithExternalLinkageNotUniqueQuery()) and
21+
not isExcluded(e, Declarations6Package::identifiersWithExternalLinkageNotUniqueQuery()) and
22+
not de = e and
23+
de.getName() = e.getName()
24+
select de, "Identifier conflicts with external identifier $@", e, e.getName()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/**
2+
* @id c/misra/identifiers-with-internal-linkage-not-unique
3+
* @name RULE-5-9: Identifiers that define objects or functions with internal linkage should be unique
4+
* @description Using non-unique identifiers can lead to developer confusion.
5+
* @kind problem
6+
* @precision very-high
7+
* @problem.severity error
8+
* @tags external/misra/id/rule-5-9
9+
* maintainability
10+
* readability
11+
* external/misra/obligation/advisory
12+
*/
13+
14+
import cpp
15+
import codingstandards.c.misra
16+
17+
from Declaration d1, Declaration d2
18+
where
19+
not isExcluded(d1, Declarations6Package::identifiersWithInternalLinkageNotUniqueQuery()) and
20+
not isExcluded(d2, Declarations6Package::identifiersWithInternalLinkageNotUniqueQuery()) and
21+
d1.isStatic() and
22+
d1.isTopLevel() and
23+
not d1 = d2 and
24+
d1.getName() = d2.getName() and
25+
// Apply an ordering based on location to enforce that (d1, d2) = (d2, d1) and we only report (d1, d2).
26+
(
27+
d1.getFile().getAbsolutePath() < d2.getFile().getAbsolutePath()
28+
or
29+
d1.getFile().getAbsolutePath() = d2.getFile().getAbsolutePath() and
30+
d1.getLocation().getStartLine() < d2.getLocation().getStartLine()
31+
)
32+
select d2, "Identifier conflicts with identifier $@ with internal linkage.", d1, d1.getName()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/**
2+
* @id c/misra/inline-function-not-declared-static-storage
3+
* @name RULE-8-10: An inline function shall be declared with the static storage class
4+
* @description Declaring an inline function with external linkage can lead to undefined or
5+
* incorrect program behaviour.
6+
* @kind problem
7+
* @precision very-high
8+
* @problem.severity error
9+
* @tags external/misra/id/rule-8-10
10+
* correctness
11+
* external/misra/obligation/required
12+
*/
13+
14+
import cpp
15+
import codingstandards.c.misra
16+
import codingstandards.cpp.Identifiers
17+
18+
from FunctionDeclarationEntry f
19+
where
20+
not isExcluded(f, Declarations6Package::inlineFunctionNotDeclaredStaticStorageQuery()) and
21+
f.getFunction() instanceof InterestingIdentifiers and
22+
f.getFunction().isInline() and
23+
not f.hasSpecifier("static")
24+
select f, "Inline function not explicitly declared static."
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/**
2+
* @id c/misra/array-external-linkage-size-explicitly-specified
3+
* @name RULE-8-11: When an array with external linkage is declared, its size should be explicitly specified
4+
* @description Declaring an array without an explicit size disallows the compiler and static
5+
* checkers from doing array bounds analysis and can lead to less readable, unsafe
6+
* code.
7+
* @kind problem
8+
* @precision very-high
9+
* @problem.severity error
10+
* @tags external/misra/id/rule-8-11
11+
* correctness
12+
* readability
13+
* external/misra/obligation/advisory
14+
*/
15+
16+
import cpp
17+
import codingstandards.c.misra
18+
import codingstandards.cpp.Identifiers
19+
20+
from VariableDeclarationEntry v, ArrayType t
21+
where
22+
not isExcluded(v, Declarations6Package::arrayExternalLinkageSizeExplicitlySpecifiedQuery()) and
23+
v.getDeclaration() instanceof ExternalIdentifiers and
24+
v.getType() = t and
25+
not exists(t.getSize()) and
26+
//this rule applies to non-defining declarations only
27+
not v.isDefinition()
28+
select v, "Array declared without explicit size."
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/**
2+
* @id c/misra/should-not-be-defined-with-external-linkage
3+
* @name RULE-8-7: Functions and objects should not be defined with external linkage if they are referenced in only one
4+
* @description Declarations with external linkage that are referenced in only one translation unit
5+
* can indicate an intention to only have those identifiers accessible in that
6+
* translation unit and accidental future accesses in other translation units can lead
7+
* to confusing program behaviour.
8+
* @kind problem
9+
* @precision very-high
10+
* @problem.severity error
11+
* @tags external/misra/id/rule-8-7
12+
* correctness
13+
* maintainability
14+
* readability
15+
* external/misra/obligation/advisory
16+
*/
17+
18+
import cpp
19+
import codingstandards.c.misra
20+
import codingstandards.cpp.Identifiers
21+
import codingstandards.cpp.Scope
22+
23+
/**
24+
* Re-introduce function calls into access description as
25+
* "any reference"
26+
*/
27+
class Reference extends NameQualifiableElement {
28+
Reference() {
29+
this instanceof Access or
30+
this instanceof FunctionCall
31+
}
32+
}
33+
34+
from ExternalIdentifiers e, Reference a1, TranslationUnit t1
35+
where
36+
not isExcluded(e, Declarations6Package::shouldNotBeDefinedWithExternalLinkageQuery()) and
37+
(a1.(Access).getTarget() = e or a1.(FunctionCall).getTarget() = e) and
38+
a1.getFile() = t1 and
39+
//not accessed in any other translation unit
40+
not exists(TranslationUnit t2, Reference a2 |
41+
not t1 = t2 and
42+
(a2.(Access).getTarget() = e or a2.(FunctionCall).getTarget() = e) and
43+
a2.getFile() = t2
44+
)
45+
select e, "Declaration with external linkage is accessed in only one translation unit $@.", a1,
46+
a1.toString()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
| test.c:4:1:4:2 | declaration of f2 | Function declaration is implicit. |
2+
| test.c:12:15:12:15 | declaration of f3 | Function declaration is implicit. |
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
rules/RULE-17-3/FunctionDeclaredImplicitly.ql

c/misra/test/rules/RULE-17-3/test.c

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// semmle-extractor-options:--clang -std=c11 -nostdinc
2+
// -I../../../../common/test/includes/standard-library
3+
double f1(double x); // COMPLIANT
4+
f2(double x); // NON_COMPLIANT
5+
6+
void f() {
7+
double l = 1;
8+
double l1 = f1(l);
9+
10+
double l2 = f2(l);
11+
12+
double l3 = f3(l); // NON_COMPLIANT
13+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
| test.c:8:7:8:7 | b | Flexible array member declared. |
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
rules/RULE-18-7/FlexibleArrayMembersDeclared.ql

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

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
struct s {
2+
int a;
3+
int b[1]; // COMPLIANT
4+
};
5+
6+
struct s1 {
7+
int a;
8+
int b[]; // NON_COMPLIANT
9+
};
10+
11+
struct s2 {
12+
int a;
13+
int b[2]; // COMPLIANT
14+
};
15+
16+
struct s3 {
17+
int a;
18+
int b[1]; // COMPLIANT
19+
int a1;
20+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
| test1.c:1:13:1:13 | f | Identifier conflicts with external identifier $@ | test.c:3:6:3:6 | f | f |
2+
| test1.c:2:7:2:7 | g | Identifier conflicts with external identifier $@ | test.c:1:5:1:5 | g | g |
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
rules/RULE-5-8/IdentifiersWithExternalLinkageNotUnique.ql

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

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
int g;
2+
extern int g1; // COMPLIANT
3+
void f() { int i; }

c/misra/test/rules/RULE-5-8/test1.c

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
static void f() { // NON_COMPLIANT
2+
int g; // NON_COMPLIANT
3+
int i; // COMPLIANT
4+
}
5+
int g1; // COMPLIANT
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
| test1.c:2:12:2:13 | g1 | Identifier conflicts with identifier $@ with internal linkage. | test.c:1:12:1:13 | g1 | g1 |
2+
| test1.c:4:13:4:13 | f | Identifier conflicts with identifier $@ with internal linkage. | test.c:2:13:2:13 | f | f |
3+
| test1.c:5:7:5:7 | g | Identifier conflicts with identifier $@ with internal linkage. | test1.c:1:12:1:12 | g | g |
4+
| test1.c:10:7:10:7 | g | Identifier conflicts with identifier $@ with internal linkage. | test1.c:1:12:1:12 | g | g |
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
rules/RULE-5-9/IdentifiersWithInternalLinkageNotUnique.ql

c/misra/test/rules/RULE-5-9/test.c

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
static int g1; // NON_COMPLIANT
2+
static void f(); // NON_COMPLIANT

c/misra/test/rules/RULE-5-9/test1.c

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
static int g; // COMPLIANT
2+
static int g1; // NON_COMPLIANT
3+
4+
static void f() { // NON_COMPLIANT
5+
int g; // NON_COMPLIANT
6+
int g2; // COMPLIANT
7+
}
8+
9+
void f1() { // COMPLIANT
10+
int g; // NON_COMPLIANT
11+
int g2; // COMPLIANT
12+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
| test.c:2:20:2:21 | declaration of f1 | Inline function not explicitly declared static. |
2+
| test.c:3:13:3:14 | declaration of f2 | Inline function not explicitly declared static. |
3+
| test.c:4:20:4:20 | declaration of f | Inline function not explicitly declared static. |
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
rules/RULE-8-10/InlineFunctionNotDeclaredStaticStorage.ql

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

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
static inline void f(); // COMPLIANT
2+
extern inline void f1(); // NON_COMPLIANT
3+
inline void f2(); // NON_COMPLIANT
4+
extern inline void f(); // NON_COMPLIANT -while this will be internal linkage it
5+
// is less clear than explicitly specifying static
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
| test.c:2:12:2:13 | declaration of a1 | Array declared without explicit size. |
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
rules/RULE-8-11/ArrayExternalLinkageSizeExplicitlySpecified.ql

0 commit comments

Comments
 (0)