Skip to content

Commit

Permalink
Fix(common/cpp): dead code alert on constexpr with array sizes.
Browse files Browse the repository at this point in the history
  • Loading branch information
fjatWbyT committed Sep 12, 2024
1 parent 4345ca0 commit c765f93
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 1 deletion.
24 changes: 23 additions & 1 deletion cpp/common/src/codingstandards/cpp/rules/deadcode/DeadCode.qll
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,31 @@ import codingstandards.cpp.Customizations
import codingstandards.cpp.Exclusions
import codingstandards.cpp.deadcode.UselessAssignments
import codingstandards.cpp.deadcode.UnreachableCode
import codingstandards.cpp.deadcode.UnusedVariables

abstract class DeadCodeSharedQuery extends Query { }

Query getQuery() { result instanceof DeadCodeSharedQuery }

/**
* Returns integer value of a constexpr variable
*/
int getConstexprValue(Variable v) {
result = v.getInitializer().getExpr().getValue().toInt() and v.isConstexpr()
}

/**
* Holds if `Variable` v is used for a local array size with value `n`
*/
bindingset[n]
predicate isUsedInLocalArraySize(Variable v, int n) {
// Cf. https://github.com/github/codeql-coding-standards/pull/660/files.
count(ArrayType at, LocalVariable arrayVariable |
arrayVariable.getType().resolveTypedefs() = at and
v.(PotentiallyUnusedLocalVariable).getFunction() = arrayVariable.getFunction() and
at.getArraySize() = n) > 0
}

/**
* Holds if the `Stmt` `s` is either dead or unreachable.
*/
Expand All @@ -39,6 +59,7 @@ predicate isDeadStmt(Stmt s) {
// - All the declarations are variable declarations
// - None of those variables are ever accessed in non-dead code
// - The initializers for each of the variables are pure
// - It isn't constexpr and used to declare an array size
exists(DeclStmt ds |
ds = s and
// Use forex so that we don't flag "fake" generated `DeclStmt`s (e.g. those generated by the
Expand All @@ -50,7 +71,8 @@ predicate isDeadStmt(Stmt s) {
not exists(VariableAccess va |
va.getTarget() = v and
not isDeadOrUnreachableStmt(va.getEnclosingStmt())
)
) and
not isUsedInLocalArraySize(v, getConstexprValue(v))
)
)
)
Expand Down
2 changes: 2 additions & 0 deletions cpp/common/test/rules/deadcode/DeadCode.expected
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,5 @@
| test.cpp:72:3:73:3 | try { ... } | This statement is dead code. |
| test.cpp:73:17:74:3 | { ... } | This statement is dead code. |
| test.cpp:79:17:80:3 | { ... } | This statement is dead code. |
| test.cpp:85:3:85:44 | declaration | This statement is dead code. |
| test.cpp:87:3:87:30 | declaration | This statement is dead code. |
5 changes: 5 additions & 0 deletions cpp/common/test/rules/deadcode/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,5 +81,10 @@ int test_dead_code(int x) {

static_assert(1); // COMPLIANT

constexpr int constexpr_array_size{6}; // COMPLIANT
int unused_array[constexpr_array_size] {}; // NON_COMPLIANT

constexpr int unused_int{2}; // NON_COMPLIANT

return live5 + live6; // COMPLIANT
}

0 comments on commit c765f93

Please sign in to comment.