Skip to content

Implement C Declarations6 package #157

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 14 commits into from
Jan 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,7 @@
"Declarations3",
"Declarations4",
"Declarations5",
"Declarations6",
"Exceptions1",
"Exceptions2",
"Expressions",
Expand Down
21 changes: 2 additions & 19 deletions c/cert/src/rules/DCL38-C/DeclaringAFlexibleArrayMember.ql
Original file line number Diff line number Diff line change
Expand Up @@ -15,29 +15,12 @@

import cpp
import codingstandards.c.cert

/**
* A member with the type array that is last in a struct
* includes any sized array (either specified or not)
*/
class FlexibleArrayMember extends MemberVariable {
Struct s;

FlexibleArrayMember() {
this.getType() instanceof ArrayType and
this.getDeclaringType() = s and
not exists(int i, int j |
s.getAMember(i) = this and
exists(s.getAMember(j)) and
j > i
)
}
}
import codingstandards.c.Variable

from VariableDeclarationEntry m, ArrayType a
where
not isExcluded(m, Declarations2Package::declaringAFlexibleArrayMemberQuery()) and
m.getType() = a and
m.getVariable() instanceof FlexibleArrayMember and
m.getVariable() instanceof FlexibleArrayMemberCandidate and
a.getArraySize() = 1
select m, "Incorrect syntax used for declaring this flexible array member."
32 changes: 32 additions & 0 deletions c/common/src/codingstandards/c/Variable.qll
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,35 @@ class VlaVariable extends Variable {
/* Extractor workaround do determine if a VLA array has the specifier volatile.*/
override predicate isVolatile() { this.getType().(ArrayType).getBaseType().isVolatile() }
}

/**
* A flexible array member
* ie member with the type array that is last in a struct
* has no size specified
*/
class FlexibleArrayMember extends FlexibleArrayMemberCandidate {
FlexibleArrayMember() {
exists(ArrayType t |
this.getType() = t and
not exists(t.getSize())
)
}
}

/**
* A member with the type array that is last in a struct
* includes any sized array (either specified or not)
*/
class FlexibleArrayMemberCandidate extends MemberVariable {
Struct s;

FlexibleArrayMemberCandidate() {
this.getType() instanceof ArrayType and
this.getDeclaringType() = s and
not exists(int i, int j |
s.getAMember(i) = this and
exists(s.getAMember(j)) and
j > i
)
}
}
29 changes: 29 additions & 0 deletions c/misra/src/rules/RULE-17-3/FunctionDeclaredImplicitly.ql
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/**
* @id c/misra/function-declared-implicitly
* @name RULE-17-3: A function shall not be declared implicitly
* @description Omission of type specifiers may not be supported by some compilers. Additionally
* implicit typing can lead to undefined behaviour.
* @kind problem
* @precision very-high
* @problem.severity error
* @tags external/misra/id/rule-17-3
* correctness
* readability
* external/misra/obligation/mandatory
*/

import cpp
import codingstandards.c.misra
import codingstandards.cpp.Identifiers

from FunctionDeclarationEntry fde
where
not isExcluded(fde, Declarations6Package::functionDeclaredImplicitlyQuery()) and
(
//use before declaration
fde.isImplicit()
or
//declared but type not explicit
isDeclaredImplicit(fde.getDeclaration())
)
select fde, "Function declaration is implicit."
19 changes: 19 additions & 0 deletions c/misra/src/rules/RULE-18-7/FlexibleArrayMembersDeclared.ql
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/**
* @id c/misra/flexible-array-members-declared
* @name RULE-18-7: Flexible array members shall not be declared
* @description The use of flexible array members can lead to unexpected program behaviour.
* @kind problem
* @precision very-high
* @problem.severity error
* @tags external/misra/id/rule-18-7
* correctness
* external/misra/obligation/required
*/

import cpp
import codingstandards.c.misra
import codingstandards.c.Variable

from FlexibleArrayMember f
where not isExcluded(f, Declarations6Package::flexibleArrayMembersDeclaredQuery())
select f, "Flexible array member declared."
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/**
* @id c/misra/identifiers-with-external-linkage-not-unique
* @name RULE-5-8: Identifiers that define objects or functions with external linkage shall be unique
* @description Using non-unique identifiers can lead to developer confusion.
* @kind problem
* @precision very-high
* @problem.severity error
* @tags external/misra/id/rule-5-8
* maintainability
* readability
* external/misra/obligation/required
*/

import cpp
import codingstandards.c.misra
import codingstandards.cpp.Identifiers

from Declaration de, ExternalIdentifiers e
where
not isExcluded(de, Declarations6Package::identifiersWithExternalLinkageNotUniqueQuery()) and
not isExcluded(e, Declarations6Package::identifiersWithExternalLinkageNotUniqueQuery()) and
not de = e and
de.getName() = e.getName()
select de, "Identifier conflicts with external identifier $@", e, e.getName()
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/**
* @id c/misra/identifiers-with-internal-linkage-not-unique
* @name RULE-5-9: Identifiers that define objects or functions with internal linkage should be unique
* @description Using non-unique identifiers can lead to developer confusion.
* @kind problem
* @precision very-high
* @problem.severity error
* @tags external/misra/id/rule-5-9
* maintainability
* readability
* external/misra/obligation/advisory
*/

import cpp
import codingstandards.c.misra

from Declaration d1, Declaration d2
where
not isExcluded(d1, Declarations6Package::identifiersWithInternalLinkageNotUniqueQuery()) and
not isExcluded(d2, Declarations6Package::identifiersWithInternalLinkageNotUniqueQuery()) and
d1.isStatic() and
d1.isTopLevel() and
not d1 = d2 and
d1.getName() = d2.getName() and
// Apply an ordering based on location to enforce that (d1, d2) = (d2, d1) and we only report (d1, d2).
(
d1.getFile().getAbsolutePath() < d2.getFile().getAbsolutePath()
or
d1.getFile().getAbsolutePath() = d2.getFile().getAbsolutePath() and
d1.getLocation().getStartLine() < d2.getLocation().getStartLine()
)
select d2, "Identifier conflicts with identifier $@ with internal linkage.", d1, d1.getName()
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/**
* @id c/misra/inline-function-not-declared-static-storage
* @name RULE-8-10: An inline function shall be declared with the static storage class
* @description Declaring an inline function with external linkage can lead to undefined or
* incorrect program behaviour.
* @kind problem
* @precision very-high
* @problem.severity error
* @tags external/misra/id/rule-8-10
* correctness
* external/misra/obligation/required
*/

import cpp
import codingstandards.c.misra
import codingstandards.cpp.Identifiers

from FunctionDeclarationEntry f
where
not isExcluded(f, Declarations6Package::inlineFunctionNotDeclaredStaticStorageQuery()) and
f.getFunction() instanceof InterestingIdentifiers and
f.getFunction().isInline() and
not f.hasSpecifier("static")
select f, "Inline function not explicitly declared static."
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/**
* @id c/misra/array-external-linkage-size-explicitly-specified
* @name RULE-8-11: When an array with external linkage is declared, its size should be explicitly specified
* @description Declaring an array without an explicit size disallows the compiler and static
* checkers from doing array bounds analysis and can lead to less readable, unsafe
* code.
* @kind problem
* @precision very-high
* @problem.severity error
* @tags external/misra/id/rule-8-11
* correctness
* readability
* external/misra/obligation/advisory
*/

import cpp
import codingstandards.c.misra
import codingstandards.cpp.Identifiers

from VariableDeclarationEntry v, ArrayType t
where
not isExcluded(v, Declarations6Package::arrayExternalLinkageSizeExplicitlySpecifiedQuery()) and
v.getDeclaration() instanceof ExternalIdentifiers and
v.getType() = t and
not exists(t.getSize()) and
//this rule applies to non-defining declarations only
not v.isDefinition()
select v, "Array declared without explicit size."
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/**
* @id c/misra/should-not-be-defined-with-external-linkage
* @name RULE-8-7: Functions and objects should not be defined with external linkage if they are referenced in only one
* @description Declarations with external linkage that are referenced in only one translation unit
* can indicate an intention to only have those identifiers accessible in that
* translation unit and accidental future accesses in other translation units can lead
* to confusing program behaviour.
* @kind problem
* @precision very-high
* @problem.severity error
* @tags external/misra/id/rule-8-7
* correctness
* maintainability
* readability
* external/misra/obligation/advisory
*/

import cpp
import codingstandards.c.misra
import codingstandards.cpp.Identifiers
import codingstandards.cpp.Scope

/**
* Re-introduce function calls into access description as
* "any reference"
*/
class Reference extends NameQualifiableElement {
Reference() {
this instanceof Access or
this instanceof FunctionCall
}
}

from ExternalIdentifiers e, Reference a1, TranslationUnit t1
where
not isExcluded(e, Declarations6Package::shouldNotBeDefinedWithExternalLinkageQuery()) and
(a1.(Access).getTarget() = e or a1.(FunctionCall).getTarget() = e) and
a1.getFile() = t1 and
//not accessed in any other translation unit
not exists(TranslationUnit t2, Reference a2 |
not t1 = t2 and
(a2.(Access).getTarget() = e or a2.(FunctionCall).getTarget() = e) and
a2.getFile() = t2
)
select e, "Declaration with external linkage is accessed in only one translation unit $@.", a1,
a1.toString()
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
| test.c:4:1:4:2 | declaration of f2 | Function declaration is implicit. |
| test.c:12:15:12:15 | declaration of f3 | Function declaration is implicit. |
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
rules/RULE-17-3/FunctionDeclaredImplicitly.ql
13 changes: 13 additions & 0 deletions c/misra/test/rules/RULE-17-3/test.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// semmle-extractor-options:--clang -std=c11 -nostdinc
// -I../../../../common/test/includes/standard-library
double f1(double x); // COMPLIANT
f2(double x); // NON_COMPLIANT

void f() {
double l = 1;
double l1 = f1(l);

double l2 = f2(l);

double l3 = f3(l); // NON_COMPLIANT
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
| test.c:8:7:8:7 | b | Flexible array member declared. |
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
rules/RULE-18-7/FlexibleArrayMembersDeclared.ql
20 changes: 20 additions & 0 deletions c/misra/test/rules/RULE-18-7/test.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
struct s {
int a;
int b[1]; // COMPLIANT
};

struct s1 {
int a;
int b[]; // NON_COMPLIANT
};

struct s2 {
int a;
int b[2]; // COMPLIANT
};

struct s3 {
int a;
int b[1]; // COMPLIANT
int a1;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
| test1.c:1:13:1:13 | f | Identifier conflicts with external identifier $@ | test.c:3:6:3:6 | f | f |
| test1.c:2:7:2:7 | g | Identifier conflicts with external identifier $@ | test.c:1:5:1:5 | g | g |
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
rules/RULE-5-8/IdentifiersWithExternalLinkageNotUnique.ql
3 changes: 3 additions & 0 deletions c/misra/test/rules/RULE-5-8/test.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
int g;
extern int g1; // COMPLIANT
void f() { int i; }
5 changes: 5 additions & 0 deletions c/misra/test/rules/RULE-5-8/test1.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
static void f() { // NON_COMPLIANT
int g; // NON_COMPLIANT
int i; // COMPLIANT
}
int g1; // COMPLIANT
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
| test1.c:2:12:2:13 | g1 | Identifier conflicts with identifier $@ with internal linkage. | test.c:1:12:1:13 | g1 | g1 |
| test1.c:4:13:4:13 | f | Identifier conflicts with identifier $@ with internal linkage. | test.c:2:13:2:13 | f | f |
| test1.c:5:7:5:7 | g | Identifier conflicts with identifier $@ with internal linkage. | test1.c:1:12:1:12 | g | g |
| 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 number Diff line number Diff line change
@@ -0,0 +1 @@
rules/RULE-5-9/IdentifiersWithInternalLinkageNotUnique.ql
2 changes: 2 additions & 0 deletions c/misra/test/rules/RULE-5-9/test.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
static int g1; // NON_COMPLIANT
static void f(); // NON_COMPLIANT
12 changes: 12 additions & 0 deletions c/misra/test/rules/RULE-5-9/test1.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
static int g; // COMPLIANT
static int g1; // NON_COMPLIANT

static void f() { // NON_COMPLIANT
int g; // NON_COMPLIANT
int g2; // COMPLIANT
}

void f1() { // COMPLIANT
int g; // NON_COMPLIANT
int g2; // COMPLIANT
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
| test.c:2:20:2:21 | declaration of f1 | Inline function not explicitly declared static. |
| test.c:3:13:3:14 | declaration of f2 | Inline function not explicitly declared static. |
| test.c:4:20:4:20 | declaration of f | Inline function not explicitly declared static. |
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
rules/RULE-8-10/InlineFunctionNotDeclaredStaticStorage.ql
5 changes: 5 additions & 0 deletions c/misra/test/rules/RULE-8-10/test.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
static inline void f(); // COMPLIANT
extern inline void f1(); // NON_COMPLIANT
inline void f2(); // NON_COMPLIANT
extern inline void f(); // NON_COMPLIANT -while this will be internal linkage it
// is less clear than explicitly specifying static
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
| test.c:2:12:2:13 | declaration of a1 | Array declared without explicit size. |
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
rules/RULE-8-11/ArrayExternalLinkageSizeExplicitlySpecified.ql
Loading