Skip to content

Commit c765f93

Browse files
committed
Fix(common/cpp): dead code alert on constexpr with array sizes.
1 parent 4345ca0 commit c765f93

File tree

3 files changed

+30
-1
lines changed

3 files changed

+30
-1
lines changed

cpp/common/src/codingstandards/cpp/rules/deadcode/DeadCode.qll

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,31 @@ import codingstandards.cpp.Customizations
1616
import codingstandards.cpp.Exclusions
1717
import codingstandards.cpp.deadcode.UselessAssignments
1818
import codingstandards.cpp.deadcode.UnreachableCode
19+
import codingstandards.cpp.deadcode.UnusedVariables
1920

2021
abstract class DeadCodeSharedQuery extends Query { }
2122

2223
Query getQuery() { result instanceof DeadCodeSharedQuery }
2324

25+
/**
26+
* Returns integer value of a constexpr variable
27+
*/
28+
int getConstexprValue(Variable v) {
29+
result = v.getInitializer().getExpr().getValue().toInt() and v.isConstexpr()
30+
}
31+
32+
/**
33+
* Holds if `Variable` v is used for a local array size with value `n`
34+
*/
35+
bindingset[n]
36+
predicate isUsedInLocalArraySize(Variable v, int n) {
37+
// Cf. https://github.com/github/codeql-coding-standards/pull/660/files.
38+
count(ArrayType at, LocalVariable arrayVariable |
39+
arrayVariable.getType().resolveTypedefs() = at and
40+
v.(PotentiallyUnusedLocalVariable).getFunction() = arrayVariable.getFunction() and
41+
at.getArraySize() = n) > 0
42+
}
43+
2444
/**
2545
* Holds if the `Stmt` `s` is either dead or unreachable.
2646
*/
@@ -39,6 +59,7 @@ predicate isDeadStmt(Stmt s) {
3959
// - All the declarations are variable declarations
4060
// - None of those variables are ever accessed in non-dead code
4161
// - The initializers for each of the variables are pure
62+
// - It isn't constexpr and used to declare an array size
4263
exists(DeclStmt ds |
4364
ds = s and
4465
// Use forex so that we don't flag "fake" generated `DeclStmt`s (e.g. those generated by the
@@ -50,7 +71,8 @@ predicate isDeadStmt(Stmt s) {
5071
not exists(VariableAccess va |
5172
va.getTarget() = v and
5273
not isDeadOrUnreachableStmt(va.getEnclosingStmt())
53-
)
74+
) and
75+
not isUsedInLocalArraySize(v, getConstexprValue(v))
5476
)
5577
)
5678
)

cpp/common/test/rules/deadcode/DeadCode.expected

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,5 @@
1212
| test.cpp:72:3:73:3 | try { ... } | This statement is dead code. |
1313
| test.cpp:73:17:74:3 | { ... } | This statement is dead code. |
1414
| test.cpp:79:17:80:3 | { ... } | This statement is dead code. |
15+
| test.cpp:85:3:85:44 | declaration | This statement is dead code. |
16+
| test.cpp:87:3:87:30 | declaration | This statement is dead code. |

cpp/common/test/rules/deadcode/test.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,5 +81,10 @@ int test_dead_code(int x) {
8181

8282
static_assert(1); // COMPLIANT
8383

84+
constexpr int constexpr_array_size{6}; // COMPLIANT
85+
int unused_array[constexpr_array_size] {}; // NON_COMPLIANT
86+
87+
constexpr int unused_int{2}; // NON_COMPLIANT
88+
8489
return live5 + live6; // COMPLIANT
8590
}

0 commit comments

Comments
 (0)