Skip to content

Package Declarations4 #101

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 16 commits into from
Jan 6, 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
2 changes: 2 additions & 0 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,8 @@
"Declarations",
"Declarations1",
"Declarations2",
"Declarations3",
"Declarations4",
"Exceptions1",
"Exceptions2",
"Expressions",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
| test.c:1:5:1:6 | definition of g1 | The identifier g1 has external linkage and is redefined $@. | test1.c:1:5:1:6 | definition of g1 | here |
| test.c:6:6:6:7 | definition of f2 | The identifier f2 has external linkage and is redefined $@. | test1.c:6:6:6:7 | definition of f2 | here |
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// GENERATED FILE - DO NOT MODIFY
import codingstandards.cpp.rules.identifierwithexternallinkageonedefinitionshared.IdentifierWithExternalLinkageOneDefinitionShared
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
int g1 = 1; // NON_COMPLIANT
static int g2 = 1; // COMPLIANT; internal linkage

inline void f1() {} // COMPLIANT; inline functions are an exception

void f2() {} // NON_COMPLIANT
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
int g1 = 0; // NON_COMPLIANT
static int g2 = 1; // COMPLIANT; internal linkage

inline void f1() {} // COMPLIANT; inline functions are an exception

void f2() {} // NON_COMPLIANT
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

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

from Macro m, InterestingIdentifiers i, string mName, string iName
where
Expand Down
2 changes: 1 addition & 1 deletion c/misra/src/rules/RULE-5-6/TypedefNameNotUnique.ql
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

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

from TypedefType t, InterestingIdentifiers d
where
Expand Down
2 changes: 1 addition & 1 deletion c/misra/src/rules/RULE-5-7/TagNameNotUnique.ql
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

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

from Struct s, InterestingIdentifiers s2
where
Expand Down
58 changes: 58 additions & 0 deletions c/misra/src/rules/RULE-8-2/FunctionTypesNotInPrototypeForm.ql
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/**
* @id c/misra/function-types-not-in-prototype-form
* @name RULE-8-2: Function types shall be in prototype form with named parameters
* @description Omission of parameter types or names prevents the compiler from doing type checking
* when those functions are used and therefore may result in undefined behaviour.
* @kind problem
* @precision medium
* @problem.severity error
* @tags external/misra/id/rule-8-2
* correctness
* external/misra/obligation/required
*/

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

/**
* `Parameter`s without names
*/
class UnnamedParameter extends Parameter {
UnnamedParameter() { not this.isNamed() }
}

/*
* This is a copy of the private `hasZeroParamDecl` predicate from the standard set of
* queries as of the `codeql-cli/2.11.2` tag in `github/codeql`.
*/

predicate hasZeroParamDecl(Function f) {
exists(FunctionDeclarationEntry fde | fde = f.getADeclarationEntry() |
not fde.isImplicit() and
not fde.hasVoidParamList() and
fde.getNumberOfParameters() = 0 and
not fde.isDefinition()
)
}

from Function f, string msg
where
not isExcluded(f, Declarations4Package::functionTypesNotInPrototypeFormQuery()) and
f instanceof InterestingIdentifiers and
(
f.getAParameter() instanceof UnnamedParameter and
msg = "Function " + f + " declares parameter that is unnamed."
or
hasZeroParamDecl(f) and
msg = "Function " + f + " does not specifiy void for no parameters present."
or
//parameters declared in declaration list (not in function signature)
//have placeholder file location associated only
exists(Parameter p |
p.getFunction() = f and
not p.getFile() = f.getFile() and
msg = "Function " + f + " declares parameter in unsupported declaration list."
)
)
select f, msg
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/**
* @id c/misra/declarations-of-a-function-same-name-and-type
* @name RULE-8-3: All declarations of a function shall use the same names and type qualifiers
* @description Using different types across the same declarations disallows strong type checking
* and can lead to undefined behaviour.
* @kind problem
* @precision very-high
* @problem.severity error
* @tags external/misra/id/rule-8-3
* correctness
* external/misra/obligation/required
*/

import cpp
import codingstandards.c.misra
import codingstandards.cpp.Compatible

from FunctionDeclarationEntry f1, FunctionDeclarationEntry f2, string case
where
not isExcluded(f1, Declarations4Package::declarationsOfAFunctionSameNameAndTypeQuery()) and
not isExcluded(f2, Declarations4Package::declarationsOfAFunctionSameNameAndTypeQuery()) and
not f1 = f2 and
f1.getDeclaration() = f2.getDeclaration() and
//return type check
(
not typesCompatible(f1.getType(), f2.getType()) and
case = "return type"
or
//parameter type check
parameterTypesIncompatible(f1, f2) and
case = "parameter types"
or
//parameter name check
parameterNamesIncompatible(f1, f2) and
case = "parameter names"
)
select f1, "The " + case + " of re-declaration of $@ is not compatible with declaration $@", f1,
f1.getName(), f2, f2.getName()
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/**
* @id c/misra/declarations-of-an-object-same-name-and-type
* @name RULE-8-3: All declarations of an object shall use the same names and type qualifiers
* @description Using different types across the same declarations disallows strong type checking
* and can lead to undefined behaviour.
* @kind problem
* @precision very-high
* @problem.severity error
* @tags external/misra/id/rule-8-3
* correctness
* external/misra/obligation/required
*/

import cpp
import codingstandards.c.misra
import codingstandards.cpp.Compatible

from VariableDeclarationEntry decl1, VariableDeclarationEntry decl2
where
not isExcluded(decl1, Declarations4Package::declarationsOfAnObjectSameNameAndTypeQuery()) and
not isExcluded(decl2, Declarations4Package::declarationsOfAnObjectSameNameAndTypeQuery()) and
not decl1 = decl2 and
decl1.getVariable().getQualifiedName() = decl2.getVariable().getQualifiedName() and
not typesCompatible(decl1.getType(), decl2.getType())
select decl1,
"The object $@ of type " + decl1.getType().toString() +
" is not compatible with re-declaration $@ of type " + decl2.getType().toString(), decl1,
decl1.getName(), decl2, decl2.getName()
50 changes: 50 additions & 0 deletions c/misra/src/rules/RULE-8-4/CompatibleDeclarationFunctionDefined.ql
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/**
* @id c/misra/compatible-declaration-function-defined
* @name RULE-8-4: A compatible declaration shall be visible when a function with external linkage is defined
* @description A compatible declaration shall be visible when a function with external linkage is
* defined, otherwise program behaviour may be undefined.
* @kind problem
* @precision very-high
* @problem.severity error
* @tags external/misra/id/rule-8-4
* readability
* maintainability
* correctness
* external/misra/obligation/required
*/

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

from FunctionDeclarationEntry f1
where
not isExcluded(f1, Declarations4Package::compatibleDeclarationFunctionDefinedQuery()) and
f1.isDefinition() and
f1.getDeclaration() instanceof ExternalIdentifiers and
//no declaration matches exactly
(
not exists(FunctionDeclarationEntry f2 |
not f2.isDefinition() and
f2.getDeclaration() = f1.getDeclaration()
)
or
//or one exists that is close but incompatible in some way
exists(FunctionDeclarationEntry f2 |
f1.getName() = f2.getName() and
not f2.isDefinition() and
f2.getDeclaration() = f1.getDeclaration() and
//return types differ
(
not typesCompatible(f1.getType(), f2.getType())
or
//parameter types differ
parameterTypesIncompatible(f1, f2)
or
//parameter names differ
parameterNamesIncompatible(f1, f2)
)
)
)
select f1, "No separate compatible declaration found for this definition."
38 changes: 38 additions & 0 deletions c/misra/src/rules/RULE-8-4/CompatibleDeclarationObjectDefined.ql
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/**
* @id c/misra/compatible-declaration-object-defined
* @name RULE-8-4: A compatible declaration shall be visible when an object with external linkage is defined
* @description A compatible declaration shall be visible when an object with external linkage is
* defined, otherwise program behaviour may be undefined.
* @kind problem
* @precision very-high
* @problem.severity error
* @tags external/misra/id/rule-8-4
* readability
* maintainability
* correctness
* external/misra/obligation/required
*/

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

from VariableDeclarationEntry decl1
where
not isExcluded(decl1, Declarations4Package::compatibleDeclarationObjectDefinedQuery()) and
decl1.isDefinition() and
decl1.getDeclaration() instanceof ExternalIdentifiers and
(
//no declaration matches exactly
not exists(VariableDeclarationEntry decl2 |
not decl2.isDefinition() and decl2.getDeclaration() = decl1.getDeclaration()
) and
//and none is close enough
not exists(VariableDeclarationEntry decl2 |
not decl2.isDefinition() and
decl1.getVariable().getQualifiedName() = decl2.getVariable().getQualifiedName() and
typesCompatible(decl1.getType(), decl2.getType())
)
)
select decl1, "No separate compatible declaration found for this definition."
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/**
* @id c/misra/identifier-with-external-linkage-one-definition
* @name RULE-8-6: An identifier with external linkage shall have exactly one definition
* @description An identifier with multiple definitions in different translation units leads to
* undefined behavior.
* @kind problem
* @precision high
* @problem.severity error
* @tags external/misra/id/rule-8-6
* correctness
* external/misra/obligation/required
*/

import cpp
import codingstandards.c.misra
import codingstandards.cpp.rules.identifierwithexternallinkageonedefinitionshared.IdentifierWithExternalLinkageOneDefinitionShared

class IdentifierWithExternalLinkageShallHaveOneDefinitionQuery extends IdentifierWithExternalLinkageOneDefinitionSharedSharedQuery {
IdentifierWithExternalLinkageShallHaveOneDefinitionQuery() {
this = Declarations4Package::identifierWithExternalLinkageOneDefinitionQuery()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
| test.c:3:6:3:7 | f1 | Function f1 declares parameter that is unnamed. |
| test.c:4:6:4:7 | f2 | Function f2 does not specifiy void for no parameters present. |
| test.c:5:6:5:7 | f3 | Function f3 does not specifiy void for no parameters present. |
| test.c:7:5:7:6 | f5 | Function f5 declares parameter in unsupported declaration list. |
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
rules/RULE-8-2/FunctionTypesNotInPrototypeForm.ql
9 changes: 9 additions & 0 deletions c/misra/test/rules/RULE-8-2/test.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
void f(int x); // COMPLIANT
void f0(void); // COMPLIANT
void f1(int); // NON_COMPLIANT
void f2(); // NON_COMPLIANT
void f3(x); // NON_COMPLIANT
void f4(const x); // NON_COMPLIANT[FALSE_NEGATIVE]
int f5(x) // NON_COMPLIANT
int x;
{ return 1; }
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
| function1.c:6:6:6:7 | declaration of f3 | The return type of re-declaration of $@ is not compatible with declaration $@ | function1.c:6:6:6:7 | declaration of f3 | f3 | function1.c:8:4:8:5 | declaration of f3 | f3 |
| function1.c:8:4:8:5 | declaration of f3 | The return type of re-declaration of $@ is not compatible with declaration $@ | function1.c:8:4:8:5 | declaration of f3 | f3 | function1.c:6:6:6:7 | declaration of f3 | f3 |
| function1.c:8:4:8:5 | declaration of f3 | The return type of re-declaration of $@ is not compatible with declaration $@ | function1.c:8:4:8:5 | declaration of f3 | f3 | function2.c:4:6:4:7 | declaration of f3 | f3 |
| function1.c:9:6:9:7 | declaration of f4 | The return type of re-declaration of $@ is not compatible with declaration $@ | function1.c:9:6:9:7 | declaration of f4 | f4 | function2.c:5:5:5:6 | declaration of f4 | f4 |
| function1.c:13:5:13:6 | definition of f6 | The return type of re-declaration of $@ is not compatible with declaration $@ | function1.c:13:5:13:6 | definition of f6 | f6 | function2.c:9:6:9:7 | definition of f6 | f6 |
| function1.c:21:3:21:5 | definition of f21 | The parameter types of re-declaration of $@ is not compatible with declaration $@ | function1.c:21:3:21:5 | definition of f21 | f21 | function2.c:17:10:17:12 | declaration of f21 | f21 |
| function1.c:25:6:25:8 | definition of f22 | The parameter names of re-declaration of $@ is not compatible with declaration $@ | function1.c:25:6:25:8 | definition of f22 | f22 | function2.c:19:13:19:15 | declaration of f22 | f22 |
| function2.c:4:6:4:7 | declaration of f3 | The return type of re-declaration of $@ is not compatible with declaration $@ | function2.c:4:6:4:7 | declaration of f3 | f3 | function1.c:8:4:8:5 | declaration of f3 | f3 |
| function2.c:5:5:5:6 | declaration of f4 | The return type of re-declaration of $@ is not compatible with declaration $@ | function2.c:5:5:5:6 | declaration of f4 | f4 | function1.c:9:6:9:7 | declaration of f4 | f4 |
| function2.c:9:6:9:7 | definition of f6 | The return type of re-declaration of $@ is not compatible with declaration $@ | function2.c:9:6:9:7 | definition of f6 | f6 | function1.c:13:5:13:6 | definition of f6 | f6 |
| function2.c:17:10:17:12 | declaration of f21 | The parameter types of re-declaration of $@ is not compatible with declaration $@ | function2.c:17:10:17:12 | declaration of f21 | f21 | function1.c:21:3:21:5 | definition of f21 | f21 |
| function2.c:19:13:19:15 | declaration of f22 | The parameter names of re-declaration of $@ is not compatible with declaration $@ | function2.c:19:13:19:15 | declaration of f22 | f22 | function1.c:25:6:25:8 | definition of f22 | f22 |
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
rules/RULE-8-3/DeclarationsOfAFunctionSameNameAndType.ql
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
| object1.c:3:6:3:7 | definition of a3 | The object $@ of type long is not compatible with re-declaration $@ of type LL | object1.c:3:6:3:7 | definition of a3 | a3 | object2.c:9:11:9:12 | declaration of a3 | a3 |
| object1.c:4:6:4:7 | definition of a4 | The object $@ of type long is not compatible with re-declaration $@ of type int | object1.c:4:6:4:7 | definition of a4 | a4 | object2.c:11:12:11:13 | declaration of a4 | a4 |
| object1.c:5:5:5:6 | definition of a5 | The object $@ of type int is not compatible with re-declaration $@ of type long | object1.c:5:5:5:6 | definition of a5 | a5 | object2.c:13:13:13:14 | declaration of a5 | a5 |
| object1.c:6:6:6:7 | definition of a6 | The object $@ of type long is not compatible with re-declaration $@ of type int | object1.c:6:6:6:7 | definition of a6 | a6 | object2.c:17:1:17:3 | declaration of a6 | a6 |
| object1.c:7:5:7:6 | definition of a7 | The object $@ of type int is not compatible with re-declaration $@ of type LL | object1.c:7:5:7:6 | definition of a7 | a7 | object2.c:19:11:19:12 | declaration of a7 | a7 |
| object1.c:13:5:13:7 | definition of a10 | The object $@ of type int[100] is not compatible with re-declaration $@ of type LI[100] | object1.c:13:5:13:7 | definition of a10 | a10 | object2.c:22:4:22:6 | definition of a10 | a10 |
| object1.c:14:5:14:7 | definition of a11 | The object $@ of type int[100] is not compatible with re-declaration $@ of type int[101] | object1.c:14:5:14:7 | definition of a11 | a11 | object2.c:23:12:23:14 | declaration of a11 | a11 |
| object1.c:17:12:17:14 | definition of a13 | The object $@ of type int *const is not compatible with re-declaration $@ of type int * | object1.c:17:12:17:14 | definition of a13 | a13 | object2.c:26:13:26:15 | declaration of a13 | a13 |
| object2.c:9:11:9:12 | declaration of a3 | The object $@ of type LL is not compatible with re-declaration $@ of type long | object2.c:9:11:9:12 | declaration of a3 | a3 | object1.c:3:6:3:7 | definition of a3 | a3 |
| object2.c:11:12:11:13 | declaration of a4 | The object $@ of type int is not compatible with re-declaration $@ of type long | object2.c:11:12:11:13 | declaration of a4 | a4 | object1.c:4:6:4:7 | definition of a4 | a4 |
| object2.c:13:13:13:14 | declaration of a5 | The object $@ of type long is not compatible with re-declaration $@ of type int | object2.c:13:13:13:14 | declaration of a5 | a5 | object1.c:5:5:5:6 | definition of a5 | a5 |
| object2.c:17:1:17:3 | declaration of a6 | The object $@ of type int is not compatible with re-declaration $@ of type long | object2.c:17:1:17:3 | declaration of a6 | a6 | object1.c:6:6:6:7 | definition of a6 | a6 |
| object2.c:19:11:19:12 | declaration of a7 | The object $@ of type LL is not compatible with re-declaration $@ of type int | object2.c:19:11:19:12 | declaration of a7 | a7 | object1.c:7:5:7:6 | definition of a7 | a7 |
| object2.c:22:4:22:6 | definition of a10 | The object $@ of type LI[100] is not compatible with re-declaration $@ of type int[100] | object2.c:22:4:22:6 | definition of a10 | a10 | object1.c:13:5:13:7 | definition of a10 | a10 |
| object2.c:23:12:23:14 | declaration of a11 | The object $@ of type int[101] is not compatible with re-declaration $@ of type int[100] | object2.c:23:12:23:14 | declaration of a11 | a11 | object1.c:14:5:14:7 | definition of a11 | a11 |
| object2.c:26:13:26:15 | declaration of a13 | The object $@ of type int * is not compatible with re-declaration $@ of type int *const | object2.c:26:13:26:15 | declaration of a13 | a13 | object1.c:17:12:17:14 | definition of a13 | a13 |
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
rules/RULE-8-3/DeclarationsOfAnObjectSameNameAndType.ql
27 changes: 27 additions & 0 deletions c/misra/test/rules/RULE-8-3/function1.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
typedef long LL;

int f1(); // COMPLIANT
int f2(int f2a); // COMPLIANT

long f3(); // NON_COMPLIANT

LL f3(); // NON_COMPLIANT
long f4(int f4a); // NON_COMPLIANT

long f5(int f5a) { return 0; } // COMPLIANT

int f6(int f6a) { return 0; } // NON_COMPLIANT

int f20(int f20a); // COMPLIANT - overloaded function

typedef int wi;
typedef int hi;
typedef long a;

a f21(wi w, wi h) { // NON_COMPLIANT
return (a)w * h;
}

void f22(int f22b, int f22a) { // NON_COMPLIANT
return;
}
Loading