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 f4e10dc

Browse filesBrowse files
authored
Merge pull request #784 from github/michaelrfairhurst/implement-deadcode-2-unused-object-definitions
Implement RULE-2-8, project should not contain unused object definitions
2 parents 8736ca7 + 3566e0f commit f4e10dc
Copy full SHA for f4e10dc

22 files changed

+958
-17
lines changed

‎c/misra/src/codeql-suites/misra-c-default.qls

Copy file name to clipboardExpand all lines: c/misra/src/codeql-suites/misra-c-default.qls
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,5 @@
77
- exclude:
88
tags contain:
99
- external/misra/audit
10+
- external/misra/strict
1011
- external/misra/default-disabled
+8Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
- description: MISRA C 2012 (Strict)
2+
- qlpack: codeql/misra-c-coding-standards
3+
- include:
4+
kind:
5+
- problem
6+
- path-problem
7+
tags contain:
8+
- external/misra/strict
+24Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/**
2+
* @id c/misra/unused-object-definition
3+
* @name RULE-2-8: A project should not contain unused object definitions
4+
* @description Object definitions which are unused should be removed.
5+
* @kind problem
6+
* @precision very-high
7+
* @problem.severity recommendation
8+
* @tags external/misra/id/rule-2-8
9+
* maintainability
10+
* performance
11+
* external/misra/c/2012/amendment4
12+
* external/misra/obligation/advisory
13+
*/
14+
15+
import cpp
16+
import codingstandards.c.misra
17+
import codingstandards.cpp.deadcode.UnusedObjects
18+
19+
from ReportDeadObject report
20+
where
21+
not isExcluded(report.getPrimaryElement(), DeadCode2Package::unusedObjectDefinitionQuery()) and
22+
not report.hasAttrUnused()
23+
select report.getPrimaryElement(), report.getMessage(), report.getOptionalPlaceholderLocation(),
24+
report.getOptionalPlaceholderMessage()
+26Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/**
2+
* @id c/misra/unused-object-definition-strict
3+
* @name RULE-2-8: A project should not contain '__attribute__((unused))' object definitions
4+
* @description A strict query which reports all unused object definitions with
5+
* '__attribute__((unused))'.
6+
* @kind problem
7+
* @precision very-high
8+
* @problem.severity recommendation
9+
* @tags external/misra/id/rule-2-8
10+
* maintainability
11+
* performance
12+
* external/misra/c/2012/amendment4
13+
* external/misra/c/strict
14+
* external/misra/obligation/advisory
15+
*/
16+
17+
import cpp
18+
import codingstandards.c.misra
19+
import codingstandards.cpp.deadcode.UnusedObjects
20+
21+
from ReportDeadObject report
22+
where
23+
not isExcluded(report.getPrimaryElement(), DeadCode2Package::unusedObjectDefinitionStrictQuery()) and
24+
report.hasAttrUnused()
25+
select report.getPrimaryElement(), report.getMessage(), report.getOptionalPlaceholderLocation(),
26+
report.getOptionalPlaceholderMessage()
+12Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
| test.c:6:5:6:6 | definition of g2 | Unused object 'g2'. | test.c:6:5:6:6 | test.c:6:5:6:6 | (ignored) |
2+
| test.c:9:5:9:6 | definition of g3 | Unused object 'g3'. | test.c:9:5:9:6 | test.c:9:5:9:6 | (ignored) |
3+
| test.c:20:7:20:8 | definition of l2 | Unused object 'l2'. | test.c:20:7:20:8 | test.c:20:7:20:8 | (ignored) |
4+
| test.c:27:7:27:8 | definition of l5 | Unused object 'l5'. | test.c:27:7:27:8 | test.c:27:7:27:8 | (ignored) |
5+
| test.c:37:10:37:11 | definition of g5 | Unused object 'g5'. | test.c:37:10:37:11 | test.c:37:10:37:11 | (ignored) |
6+
| test.c:45:9:45:10 | definition of g6 | Unused object 'g6'. | test.c:45:9:45:10 | test.c:45:9:45:10 | (ignored) |
7+
| test.c:51:5:51:6 | definition of g7 | Unused object 'g7'. | test.c:51:5:51:6 | test.c:51:5:51:6 | (ignored) |
8+
| test.c:64:3:64:18 | ONLY_DEF_VAR(x) | Invocation of macro '$@' defines unused object 'l2'. | test.c:60:1:60:34 | test.c:60:1:60:34 | ONLY_DEF_VAR |
9+
| test.c:68:1:71:5 | #define ALSO_DEF_VAR(x) int x = 0; while (1) ; | Macro 'ALSO_DEF_VAR' defines unused object with an invocation-dependent name, for example, '$@'. | test.c:73:16:73:17 | test.c:73:16:73:17 | l1 |
10+
| test.c:77:1:82:3 | #define DEF_UNUSED_INNER_VAR() { int _v = 0; while (1) ; } | Macro 'DEF_UNUSED_INNER_VAR' defines unused object '_v'. | test.c:77:1:82:3 | test.c:77:1:82:3 | (ignored) |
11+
| test.c:119:11:119:13 | definition of g10 | Unused object 'g10'. | test.c:119:11:119:13 | test.c:119:11:119:13 | (ignored) |
12+
| test.c:124:13:124:14 | definition of l2 | Unused object 'l2'. | test.c:124:13:124:14 | test.c:124:13:124:14 | (ignored) |
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
rules/RULE-2-8/UnusedObjectDefinition.ql
+4Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
| test.c:87:29:87:30 | definition of g8 | Unused object 'g8'. | test.c:87:29:87:30 | test.c:87:29:87:30 | (ignored) |
2+
| test.c:92:3:92:30 | ONLY_DEF_ATTR_UNUSED_VAR(x) | Invocation of macro '$@' defines unused object 'l2'. | test.c:88:1:88:70 | test.c:88:1:88:70 | ONLY_DEF_ATTR_UNUSED_VAR |
3+
| test.c:96:1:99:5 | #define ALSO_DEF_ATTR_UNUSED_VAR(x) __attribute__((unused)) int x = 0; while (1) ; | Macro 'ALSO_DEF_ATTR_UNUSED_VAR' defines unused object with an invocation-dependent name, for example, '$@'. | test.c:101:28:101:29 | test.c:101:28:101:29 | l1 |
4+
| test.c:106:1:111:3 | #define DEF_ATTR_UNUSED_INNER_VAR() { __attribute__((unused)) int _v = 0; while (1) ; } | Macro 'DEF_ATTR_UNUSED_INNER_VAR' defines unused object '_v'. | test.c:106:1:111:3 | test.c:106:1:111:3 | (ignored) |
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
rules/RULE-2-8/UnusedObjectDefinitionStrict.ql

‎c/misra/test/rules/RULE-2-8/test.c

Copy file name to clipboard
+133Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
// Not a definition, only a declaration:
2+
extern int g1; // COMPLIANT
3+
4+
// Both declared + defined:
5+
extern int g2; // COMPLIANT
6+
int g2 = 1; // NON_COMPLIANT
7+
8+
// Definition is only declaration:
9+
int g3 = 1; // NON_COMPLIANT
10+
11+
// Definition, but value is required for program to compile:
12+
int g4 = 1; // COMPLIANT
13+
void f1() { g4; }
14+
15+
// Local variables:
16+
void f2() {
17+
int l1; // COMPLIANT
18+
l1;
19+
20+
int l2; // NON-COMPLIANT
21+
22+
// Value is required for the program to compile:
23+
int l3; // COMPLIANT
24+
sizeof(l3);
25+
26+
int l4, // COMPLIANT
27+
l5; // NON-COMPLIANT
28+
l4;
29+
}
30+
31+
// Struct fields are not objects:
32+
struct s {
33+
int x; // COMPLIANT
34+
};
35+
36+
// Declaration of type struct is an object:
37+
struct s g5; // NON-COMPLIANT
38+
39+
// Struct fields are not objects:
40+
union u {
41+
int x; // COMPLIANT
42+
};
43+
44+
// Declaration of type union is an object:
45+
union u g6; // NON-COMPLIANT
46+
47+
// Typedefs are not objects:
48+
typedef int td1; // COMPLIANT
49+
50+
// Declaration of typedef type object:
51+
td1 g7; // NON-COMPLIANT
52+
53+
// Function parameters are not objects:
54+
void f3(int p) {} // COMPLIANT
55+
56+
// Function type parameters are not objects:
57+
typedef int td2(int x); // COMPLIANT
58+
59+
// Macros that define unused vars tests:
60+
#define ONLY_DEF_VAR(x) int x = 0;
61+
void f4() {
62+
ONLY_DEF_VAR(l1); // COMPLIANT
63+
l1;
64+
ONLY_DEF_VAR(l2); // NON-COMPLIANT
65+
}
66+
67+
// NON-COMPLIANT
68+
#define ALSO_DEF_VAR(x) \
69+
int x = 0; \
70+
while (1) \
71+
;
72+
void f5() {
73+
ALSO_DEF_VAR(l1); // COMPLIANT
74+
ALSO_DEF_VAR(l2); // COMPLIANT
75+
}
76+
77+
#define DEF_UNUSED_INNER_VAR() \
78+
{ \
79+
int _v = 0; \
80+
while (1) \
81+
; \
82+
} // NON-COMPLIANT
83+
void f6() {
84+
DEF_UNUSED_INNER_VAR(); // COMPLIANT
85+
}
86+
87+
__attribute__((unused)) int g8 = 1; // NON-COMPLIANT
88+
#define ONLY_DEF_ATTR_UNUSED_VAR(x) __attribute__((unused)) int x = 0;
89+
void f7() {
90+
ONLY_DEF_ATTR_UNUSED_VAR(l1); // COMPLIANT
91+
l1;
92+
ONLY_DEF_ATTR_UNUSED_VAR(l2); // NON-COMPLIANT
93+
}
94+
95+
// NON-COMPLIANT
96+
#define ALSO_DEF_ATTR_UNUSED_VAR(x) \
97+
__attribute__((unused)) int x = 0; \
98+
while (1) \
99+
;
100+
void f8() {
101+
ALSO_DEF_ATTR_UNUSED_VAR(l1); // COMPLIANT
102+
ALSO_DEF_ATTR_UNUSED_VAR(l2); // COMPLIANT
103+
}
104+
105+
// NON-COMPLIANT
106+
#define DEF_ATTR_UNUSED_INNER_VAR() \
107+
{ \
108+
__attribute__((unused)) int _v = 0; \
109+
while (1) \
110+
; \
111+
}
112+
113+
void f9() {
114+
DEF_ATTR_UNUSED_INNER_VAR(); // COMPLIANT
115+
}
116+
117+
// Const variable tests:
118+
const int g9 = 1; // COMPLIANT
119+
const int g10 = 1; // NON-COMPLIANT
120+
121+
void f10() {
122+
g9;
123+
const int l1 = 1; // COMPLIANT
124+
const int l2 = 1; // NON-COMPLIANT
125+
l1;
126+
}
127+
128+
// Side effects should not disable this rule:
129+
void f11() {
130+
int l1 = 1; // COMPLIANT
131+
int l2 = l1++; // COMPLIANT
132+
l2;
133+
}

‎cpp/common/src/codingstandards/cpp/AlertReporting.qll

Copy file name to clipboardExpand all lines: cpp/common/src/codingstandards/cpp/AlertReporting.qll
+25-3Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,24 +18,46 @@ module MacroUnwrapper<ResultType ResultElement> {
1818
}
1919

2020
/**
21-
* Gets the primary macro that generated the result element.
21+
* Gets the primary macro invocation that generated the result element.
2222
*/
23-
Macro getPrimaryMacro(ResultElement re) {
23+
MacroInvocation getPrimaryMacroInvocation(ResultElement re) {
2424
exists(MacroInvocation mi |
2525
mi = getAMacroInvocation(re) and
2626
// No other more specific macro that expands to element
2727
not exists(MacroInvocation otherMi |
2828
otherMi = getAMacroInvocation(re) and otherMi.getParentInvocation() = mi
2929
) and
30-
result = mi.getMacro()
30+
result = mi
3131
)
3232
}
3333

34+
/**
35+
* Gets the primary macro that generated the result element.
36+
*/
37+
Macro getPrimaryMacro(ResultElement re) { result = getPrimaryMacroInvocation(re).getMacro() }
38+
3439
/**
3540
* If a result element is expanded from a macro invocation, then return the "primary" macro that
3641
* generated the element, otherwise return the element itself.
3742
*/
3843
Element unwrapElement(ResultElement re) {
3944
if exists(getPrimaryMacro(re)) then result = getPrimaryMacro(re) else result = re
4045
}
46+
47+
/* Final class so we can extend it */
48+
final private class FinalMacroInvocation = MacroInvocation;
49+
50+
/* A macro invocation that expands to create a `ResultElement` */
51+
class ResultMacroExpansion extends FinalMacroInvocation {
52+
ResultElement re;
53+
54+
ResultMacroExpansion() { re = getAnExpandedElement() }
55+
56+
ResultElement getResultElement() { result = re }
57+
}
58+
59+
/* The most specific macro invocation that expands to create this `ResultElement`. */
60+
class PrimaryMacroExpansion extends ResultMacroExpansion {
61+
PrimaryMacroExpansion() { this = getPrimaryMacroInvocation(re) }
62+
}
4163
}

0 commit comments

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