Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit bdd3865

Browse filesBrowse files
authored
Merge branch 'main' into codeql/upgrade-to-2.16.6
2 parents f718e2a + 1566129 commit bdd3865
Copy full SHA for bdd3865

24 files changed

+410
-57
lines changed
+18-7Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,44 @@
11
import cpp
2+
import codingstandards.cpp.Pointers
23
import codingstandards.cpp.UndefinedBehavior
34

45
/**
56
* Library for modeling undefined behavior.
67
*/
78
abstract class CUndefinedBehavior extends UndefinedBehavior { }
89

10+
/**
11+
* A function which has the signature - but not the name - of a main function.
12+
*/
913
class C99MainFunction extends Function {
1014
C99MainFunction() {
1115
this.getNumberOfParameters() = 2 and
12-
this.getType() instanceof IntType and
13-
this.getParameter(0).getType() instanceof IntType and
14-
this.getParameter(1).getType().(PointerType).getBaseType().(PointerType).getBaseType()
15-
instanceof CharType
16+
this.getType().getUnderlyingType() instanceof IntType and
17+
this.getParameter(0).getType().getUnderlyingType() instanceof IntType and
18+
this.getParameter(1)
19+
.getType()
20+
.getUnderlyingType()
21+
.(UnspecifiedPointerOrArrayType)
22+
.getBaseType()
23+
.(UnspecifiedPointerOrArrayType)
24+
.getBaseType() instanceof CharType
1625
or
1726
this.getNumberOfParameters() = 0 and
18-
this.getType() instanceof VoidType
27+
// Must be explicitly declared as `int main(void)`.
28+
this.getADeclarationEntry().hasVoidParamList() and
29+
this.getType().getUnderlyingType() instanceof IntType
1930
}
2031
}
2132

2233
class CUndefinedMainDefinition extends CUndefinedBehavior, Function {
2334
CUndefinedMainDefinition() {
2435
// for testing purposes, we use the prefix ____codeql_coding_standards`
25-
(this.getName() = "main" or this.getName().indexOf("____codeql_coding_standards") = 0) and
36+
(this.getName() = "main" or this.getName().indexOf("____codeql_coding_standards_main") = 0) and
2637
not this instanceof C99MainFunction
2738
}
2839

2940
override string getReason() {
3041
result =
31-
"The behavior of the program is undefined because the main function is not defined according to the C standard."
42+
"main function may trigger undefined behavior because it is not in one of the formats specified by the C standard."
3243
}
3344
}

‎c/misra/src/rules/RULE-1-3/OccurrenceOfUndefinedBehavior.ql

Copy file name to clipboardExpand all lines: c/misra/src/rules/RULE-1-3/OccurrenceOfUndefinedBehavior.ql
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,4 @@ import codingstandards.c.UndefinedBehavior
1818

1919
from CUndefinedBehavior c
2020
where not isExcluded(c, Language3Package::occurrenceOfUndefinedBehaviorQuery())
21-
select c, "May result in undefined behavior."
21+
select c, c.getReason()

‎c/misra/src/rules/RULE-5-4/MacroIdentifiersNotDistinct.ql

Copy file name to clipboardExpand all lines: c/misra/src/rules/RULE-5-4/MacroIdentifiersNotDistinct.ql
+84-8Lines changed: 84 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,56 @@
1515

1616
import cpp
1717
import codingstandards.c.misra
18+
import codingstandards.cpp.Macro
19+
import codingstandards.cpp.Includes
20+
import codingstandards.cpp.PreprocessorDirective
1821

19-
from Macro m, Macro m2
22+
/**
23+
* Gets a top level element that this macro is expanded to, e.g. an element which does not also have
24+
* an enclosing element in the macro.
25+
*/
26+
Element getATopLevelElement(MacroInvocation mi) {
27+
result = mi.getAnExpandedElement() and
28+
not result.getEnclosingElement() = mi.getAnExpandedElement() and
29+
not result instanceof Conversion
30+
}
31+
32+
/**
33+
* Gets a link target that this macro is expanded in.
34+
*/
35+
LinkTarget getALinkTarget(Macro m) {
36+
exists(MacroInvocation mi, Element e |
37+
mi = m.getAnInvocation() and
38+
e = getATopLevelElement(mi)
39+
|
40+
result = e.(Expr).getEnclosingFunction().getALinkTarget()
41+
or
42+
result = e.(Stmt).getEnclosingFunction().getALinkTarget()
43+
or
44+
exists(GlobalOrNamespaceVariable g |
45+
result = g.getALinkTarget() and
46+
g = e.(Expr).getEnclosingDeclaration()
47+
)
48+
)
49+
}
50+
51+
/**
52+
* Holds if the m1 and m2 are unconditionally included from a common file.
53+
*
54+
* Extracted out for performance reasons - otherwise the call to determine the file path for the
55+
* message was specializing the calls to `getAnUnconditionallyIncludedFile*(..)` and causing
56+
* slow performance.
57+
*/
58+
bindingset[m1, m2]
59+
pragma[inline_late]
60+
private predicate isIncludedUnconditionallyFromCommonFile(Macro m1, Macro m2) {
61+
exists(File f |
62+
getAnUnconditionallyIncludedFile*(f) = m1.getFile() and
63+
getAnUnconditionallyIncludedFile*(f) = m2.getFile()
64+
)
65+
}
66+
67+
from Macro m, Macro m2, string message
2068
where
2169
not isExcluded(m, Declarations1Package::macroIdentifiersNotDistinctQuery()) and
2270
not m = m2 and
@@ -25,12 +73,40 @@ where
2573
//C90 states the first 31 characters of macro identifiers are significant and is not currently considered by this rule
2674
//ie an identifier differing on the 32nd character would be indistinct for C90 but distinct for C99
2775
//and is currently not reported by this rule
28-
if m.getName().length() >= 64
29-
then m.getName().prefix(63) = m2.getName().prefix(63)
30-
else m.getName() = m2.getName()
76+
if m.getName().length() >= 64 and not m.getName() = m2.getName()
77+
then (
78+
m.getName().prefix(63) = m2.getName().prefix(63) and
79+
message =
80+
"Macro identifer " + m.getName() + " is nondistinct in first 63 characters, compared to $@."
81+
) else (
82+
m.getName() = m2.getName() and
83+
message =
84+
"Definition of macro " + m.getName() +
85+
" is not distinct from alternative definition of $@ in " +
86+
m2.getLocation().getFile().getRelativePath() + "."
87+
)
3188
) and
3289
//reduce double report since both macros are in alert, arbitrary ordering
33-
m.getLocation().getStartLine() >= m2.getLocation().getStartLine()
34-
select m,
35-
"Macro identifer " + m.getName() + " is nondistinct in first 63 characters, compared to $@.", m2,
36-
m2.getName()
90+
m.getLocation().getStartLine() >= m2.getLocation().getStartLine() and
91+
// Not within an #ifndef MACRO_NAME
92+
not exists(PreprocessorIfndef ifBranch |
93+
m.getAGuard() = ifBranch or
94+
m2.getAGuard() = ifBranch
95+
|
96+
ifBranch.getHead() = m.getName()
97+
) and
98+
// Must be included unconditionally from the same file, otherwise m1 may not be defined
99+
// when m2 is defined
100+
isIncludedUnconditionallyFromCommonFile(m, m2) and
101+
// Macros can't be mutually exclusive
102+
not mutuallyExclusiveBranchDirectiveMacros(m, m2) and
103+
not mutuallyExclusiveBranchDirectiveMacros(m2, m) and
104+
// If at least one invocation exists for at least one of the macros, then they must share a link
105+
// target - i.e. must both be expanded in the same context
106+
(
107+
(exists(m.getAnInvocation()) and exists(m2.getAnInvocation()))
108+
implies
109+
// Must share a link target - e.g. must both be expanded in the same context
110+
getALinkTarget(m) = getALinkTarget(m2)
111+
)
112+
select m, message, m2, m2.getName()

‎c/misra/src/rules/RULE-8-13/PointerShouldPointToConstTypeWhenPossible.ql

Copy file name to clipboardExpand all lines: c/misra/src/rules/RULE-8-13/PointerShouldPointToConstTypeWhenPossible.ql
+49-24Lines changed: 49 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -18,29 +18,54 @@ import cpp
1818
import codingstandards.c.misra
1919
import codingstandards.cpp.Pointers
2020
import codingstandards.cpp.SideEffect
21+
import codingstandards.cpp.alertreporting.HoldsForAllCopies
2122

22-
from Variable ptr, PointerOrArrayType type
23+
class NonConstPointerVariableCandidate extends Variable {
24+
NonConstPointerVariableCandidate() {
25+
// Ignore parameters in functions without bodies
26+
(this instanceof Parameter implies exists(this.(Parameter).getFunction().getBlock())) and
27+
// Ignore variables in functions that use ASM commands
28+
not exists(AsmStmt a |
29+
a.getEnclosingFunction() = this.(LocalScopeVariable).getFunction()
30+
or
31+
// In a type declared locally
32+
this.(Field).getDeclaringType+().getEnclosingFunction() = a.getEnclosingFunction()
33+
) and
34+
exists(PointerOrArrayType type |
35+
// include only pointers which point to a const-qualified type
36+
this.getType() = type and
37+
not type.isDeeplyConstBelow()
38+
) and
39+
// exclude pointers passed as arguments to functions which take a
40+
// parameter that points to a non-const-qualified type
41+
not exists(FunctionCall fc, int i |
42+
fc.getArgument(i) = this.getAnAccess() and
43+
not fc.getTarget().getParameter(i).getType().isDeeplyConstBelow()
44+
) and
45+
// exclude any pointers which have their underlying data modified
46+
not exists(VariableEffect effect |
47+
effect.getTarget() = this and
48+
// but not pointers that are only themselves modified
49+
not effect.(AssignExpr).getLValue() = this.getAnAccess() and
50+
not effect.(CrementOperation).getOperand() = this.getAnAccess()
51+
) and
52+
// exclude pointers assigned to another pointer to a non-const-qualified type
53+
not exists(Variable a |
54+
a.getAnAssignedValue() = this.getAnAccess() and
55+
not a.getType().(PointerOrArrayType).isDeeplyConstBelow()
56+
)
57+
}
58+
}
59+
60+
/**
61+
* Ensure that all copies of a variable are considered to be missing const qualification to avoid
62+
* false positives where a variable is only used/modified in a single copy.
63+
*/
64+
class NonConstPointerVariable =
65+
HoldsForAllCopies<NonConstPointerVariableCandidate, Variable>::LogicalResultElement;
66+
67+
from NonConstPointerVariable ptr
2368
where
24-
not isExcluded(ptr, Pointers1Package::pointerShouldPointToConstTypeWhenPossibleQuery()) and
25-
// include only pointers which point to a const-qualified type
26-
ptr.getType() = type and
27-
not type.isDeeplyConstBelow() and
28-
// exclude pointers passed as arguments to functions which take a
29-
// parameter that points to a non-const-qualified type
30-
not exists(FunctionCall fc, int i |
31-
fc.getArgument(i) = ptr.getAnAccess() and
32-
not fc.getTarget().getParameter(i).getType().isDeeplyConstBelow()
33-
) and
34-
// exclude any pointers which have their underlying data modified
35-
not exists(VariableEffect effect |
36-
effect.getTarget() = ptr and
37-
// but not pointers that are only themselves modified
38-
not effect.(AssignExpr).getLValue() = effect.getAnAccess() and
39-
not effect.(CrementOperation).getOperand() = effect.getAnAccess()
40-
) and
41-
// exclude pointers assigned to another pointer to a non-const-qualified type
42-
not exists(Variable a |
43-
a.getAnAssignedValue() = ptr.getAnAccess() and
44-
not a.getType().(PointerOrArrayType).isDeeplyConstBelow()
45-
)
46-
select ptr, "$@ points to a non-const-qualified type.", ptr, ptr.getName()
69+
not isExcluded(ptr.getAnElementInstance(),
70+
Pointers1Package::pointerShouldPointToConstTypeWhenPossibleQuery())
71+
select ptr, "$@ points to a non-const-qualified type.", ptr, ptr.getAnElementInstance().getName()
+8-5Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
1-
| test.c:8:6:8:35 | ____codeql_coding_standards_m2 | May result in undefined behavior. |
2-
| test.c:11:5:11:34 | ____codeql_coding_standards_m3 | May result in undefined behavior. |
3-
| test.c:15:5:15:34 | ____codeql_coding_standards_m4 | May result in undefined behavior. |
4-
| test.c:19:5:19:34 | ____codeql_coding_standards_m5 | May result in undefined behavior. |
5-
| test.c:23:5:23:34 | ____codeql_coding_standards_m6 | May result in undefined behavior. |
1+
| test.c:4:6:4:38 | ____codeql_coding_standards_main1 | main function may trigger undefined behavior because it is not in one of the formats specified by the C standard. |
2+
| test.c:8:5:8:37 | ____codeql_coding_standards_main2 | main function may trigger undefined behavior because it is not in one of the formats specified by the C standard. |
3+
| test.c:27:5:27:37 | ____codeql_coding_standards_main6 | main function may trigger undefined behavior because it is not in one of the formats specified by the C standard. |
4+
| test.c:32:6:32:38 | ____codeql_coding_standards_main7 | main function may trigger undefined behavior because it is not in one of the formats specified by the C standard. |
5+
| test.c:36:5:36:37 | ____codeql_coding_standards_main8 | main function may trigger undefined behavior because it is not in one of the formats specified by the C standard. |
6+
| test.c:40:5:40:37 | ____codeql_coding_standards_main9 | main function may trigger undefined behavior because it is not in one of the formats specified by the C standard. |
7+
| test.c:44:5:44:38 | ____codeql_coding_standards_main10 | main function may trigger undefined behavior because it is not in one of the formats specified by the C standard. |
8+
| test.c:48:5:48:38 | ____codeql_coding_standards_main11 | main function may trigger undefined behavior because it is not in one of the formats specified by the C standard. |

‎c/misra/test/rules/RULE-1-3/test.c

Copy file name to clipboard
+32-7Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,50 @@
1-
void main(void) { // COMPLIANT
1+
int main(void) { // COMPLIANT
22
}
33

4-
int ____codeql_coding_standards_m1(int argc, char **argv) { // NON_COMPLIANT
4+
void ____codeql_coding_standards_main1(void) { // NON_COMPLIANT
55
return 0;
66
}
77

8-
void ____codeql_coding_standards_m2(char *argc, char **argv) { // NON_COMPLIANT
8+
int ____codeql_coding_standards_main2() { // NON_COMPLIANT
9+
return 0;
10+
}
11+
12+
int ____codeql_coding_standards_main3(int argc, char **argv) { // COMPLIANT
13+
return 0;
14+
}
15+
16+
int ____codeql_coding_standards_main4(int argc, char argv[][]) { // COMPLIANT
17+
return 0;
18+
}
19+
20+
int ____codeql_coding_standards_main5(int argc, char *argv[]) { // COMPLIANT
21+
return 0;
22+
}
23+
24+
typedef int MY_INT;
25+
typedef char *MY_CHAR_PTR;
26+
27+
int ____codeql_coding_standards_main6(MY_INT argc,
28+
MY_CHAR_PTR argv[]) { // COMPLIANT
29+
return 0;
30+
}
31+
32+
void ____codeql_coding_standards_main7(char *argc,
33+
char **argv) { // NON_COMPLIANT
934
}
1035

11-
int ____codeql_coding_standards_m3(int argc, char *argv) { // NON_COMPLIANT
36+
int ____codeql_coding_standards_main8(int argc, char *argv) { // NON_COMPLIANT
1237
return 0;
1338
}
1439

15-
int ____codeql_coding_standards_m4() { // NON_COMPLIANT
40+
int ____codeql_coding_standards_main9() { // NON_COMPLIANT
1641
return 0;
1742
}
1843

19-
int ____codeql_coding_standards_m5(int argc, int *argv) { // NON_COMPLIANT
44+
int ____codeql_coding_standards_main10(int argc, int *argv) { // NON_COMPLIANT
2045
return 0;
2146
}
2247

23-
int ____codeql_coding_standards_m6(int argc, int **argv) { // NON_COMPLIANT
48+
int ____codeql_coding_standards_main11(int argc, int **argv) { // NON_COMPLIANT
2449
return 0;
2550
}
+3-1Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
1+
| header3.h:7:1:7:24 | #define MULTIPLE_INCLUDE | Definition of macro MULTIPLE_INCLUDE is not distinct from alternative definition of $@ in rules/RULE-5-4/header4.h. | header4.h:1:1:1:24 | #define MULTIPLE_INCLUDE | MULTIPLE_INCLUDE |
2+
| header3.h:14:1:14:21 | #define NOT_PROTECTED | Definition of macro NOT_PROTECTED is not distinct from alternative definition of $@ in rules/RULE-5-4/header4.h. | header4.h:12:1:12:23 | #define NOT_PROTECTED 1 | NOT_PROTECTED |
13
| test.c:2:1:2:72 | #define iltiqzxgfqsgigwfuyntzghvzltueatcxqnqofnnvjyszmcsylyohvqaosjbqyyB | Macro identifer iltiqzxgfqsgigwfuyntzghvzltueatcxqnqofnnvjyszmcsylyohvqaosjbqyyB is nondistinct in first 63 characters, compared to $@. | test.c:1:1:1:72 | #define iltiqzxgfqsgigwfuyntzghvzltueatcxqnqofnnvjyszmcsylyohvqaosjbqyyA | iltiqzxgfqsgigwfuyntzghvzltueatcxqnqofnnvjyszmcsylyohvqaosjbqyyA |
2-
| test.c:8:1:8:31 | #define FUNCTION_MACRO(X) X + 1 | Macro identifer FUNCTION_MACRO is nondistinct in first 63 characters, compared to $@. | test.c:7:1:7:57 | #define FUNCTION_MACRO(FUNCTION_MACRO) FUNCTION_MACRO + 1 | FUNCTION_MACRO |
4+
| test.c:8:1:8:31 | #define FUNCTION_MACRO(X) X + 1 | Definition of macro FUNCTION_MACRO is not distinct from alternative definition of $@ in rules/RULE-5-4/test.c. | test.c:7:1:7:57 | #define FUNCTION_MACRO(FUNCTION_MACRO) FUNCTION_MACRO + 1 | FUNCTION_MACRO |
+11Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#ifdef FOO
2+
#include "header1.h"
3+
#else
4+
#include "header2.h"
5+
#endif
6+
7+
#ifdef FOO
8+
#define A_MACRO 1 // COMPLIANT
9+
#else
10+
#define A_MACRO 2 // COMPLIANT
11+
#endif

‎c/misra/test/rules/RULE-5-4/header1.h

Copy file name to clipboard
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
#define REPEATED 11 // COMPLIANT

‎c/misra/test/rules/RULE-5-4/header2.h

Copy file name to clipboard
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
#define REPEATED 1 // COMPLIANT

‎c/misra/test/rules/RULE-5-4/header3.h

Copy file name to clipboard
+16Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#ifndef HEADER3_H
2+
#define HEADER3_H
3+
4+
// We should ignore the header guards in this file
5+
6+
// This is defined unconditionally by both header3.h and header4.h
7+
#define MULTIPLE_INCLUDE // NON_COMPLIANT
8+
9+
// This is redefined in header3.h, but only if it isn't already defined
10+
#define PROTECTED // COMPLIANT
11+
12+
// This is redefined in header3.h, but is conditional on some other condition,
13+
// so this is redefined
14+
#define NOT_PROTECTED // NON_COMPLIANT
15+
16+
#endif

‎c/misra/test/rules/RULE-5-4/header4.h

Copy file name to clipboard
+13Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#define MULTIPLE_INCLUDE // NON_COMPLIANT
2+
3+
// This case is triggered from root2.c
4+
// because PROTECTED isn't defined in
5+
// that case
6+
#ifndef PROTECTED
7+
#define PROTECTED // COMPLIANT - checked by guard
8+
#endif
9+
10+
// Always enabled, so conflicts in root1.c case
11+
#ifdef MULTIPLE_INCLUDE
12+
#define NOT_PROTECTED 1 // NON_COMPLIANT
13+
#endif

‎c/misra/test/rules/RULE-5-4/root1.c

Copy file name to clipboard
+6Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#define FOO 1
2+
#include "conditional.h"
3+
4+
// Both headers define MULTIPLE_INCLUDE
5+
#include "header3.h"
6+
#include "header4.h"

‎c/misra/test/rules/RULE-5-4/root2.c

Copy file name to clipboard
+3Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
#include "conditional.h"
2+
3+
#include "header4.h"

‎c/misra/test/rules/RULE-8-13/PointerShouldPointToConstTypeWhenPossible.expected

Copy file name to clipboardExpand all lines: c/misra/test/rules/RULE-8-13/PointerShouldPointToConstTypeWhenPossible.expected
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,4 @@
1212
| test.c:66:23:66:24 | p1 | $@ points to a non-const-qualified type. | test.c:66:23:66:24 | p1 | p1 |
1313
| test.c:71:17:71:18 | p1 | $@ points to a non-const-qualified type. | test.c:71:17:71:18 | p1 | p1 |
1414
| test.c:75:15:75:16 | p1 | $@ points to a non-const-qualified type. | test.c:75:15:75:16 | p1 | p1 |
15+
| test.c:103:30:103:30 | s | $@ points to a non-const-qualified type. | test.c:103:30:103:30 | s | s |

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.