Skip to content

Commit 225d24e

Browse files
committed
DeadCode: Create shared implementations for the cpp queries
Create shared implementations in preparation for the C queries.
1 parent 4acb620 commit 225d24e

29 files changed

+247
-170
lines changed

cpp/autosar/src/rules/A0-1-4/UnusedParameter.ql

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,8 @@
1616
import cpp
1717
import codingstandards.cpp.autosar
1818
import codingstandards.cpp.deadcode.UnusedParameters
19+
import codingstandards.cpp.rules.unusedparameter.UnusedParameter
1920

20-
from Function f, UnusedParameter p
21-
where
22-
not isExcluded(p, DeadCodePackage::unusedParameterQuery()) and
23-
f = p.getFunction() and
24-
// Virtual functions are covered by a different rule
25-
not f.isVirtual()
26-
select p, "Unused parameter '" + p.getName() + "' for function $@.", f, f.getQualifiedName()
21+
class UnusedParameterQuery extends UnusedParameterSharedQuery {
22+
UnusedParameterQuery() { this = DeadCodePackage::unusedParameterQuery() }
23+
}

cpp/autosar/src/rules/A0-1-6/UnusedTypeDeclarations.ql

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,8 @@
1616

1717
import cpp
1818
import codingstandards.cpp.autosar
19-
import codingstandards.cpp.TypeUses
19+
import codingstandards.cpp.rules.unusedtypedeclarations.UnusedTypeDeclarations
2020

21-
from UserType ut
22-
where
23-
not isExcluded(ut, DeadCodePackage::unusedTypeDeclarationsQuery()) and
24-
not ut instanceof TemplateParameter and
25-
not ut instanceof ProxyClass and
26-
not exists(getATypeUse(ut)) and
27-
not ut.isFromUninstantiatedTemplate(_)
28-
select ut, "Type declaration " + ut.getName() + " is not used."
21+
class UnusedTypeDeclarationsQuery extends UnusedTypeDeclarationsSharedQuery {
22+
UnusedTypeDeclarationsQuery() { this = DeadCodePackage::unusedTypeDeclarationsQuery() }
23+
}

cpp/autosar/src/rules/M0-1-1/UnreachableCode.ql

Lines changed: 4 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -17,39 +17,8 @@
1717
import cpp
1818
import codingstandards.cpp.autosar
1919
import codingstandards.cpp.deadcode.UnreachableCode
20+
import codingstandards.cpp.rules.unreachablecode.UnreachableCode
2021

21-
/*
22-
* This query identifies unreachable code at the level of `BasicBlock`. We use `BasicBlock`s for
23-
* this because they represent sequences of statements which, according to the CFG, are either
24-
* all unreachable or all reachable, because control flow cannot escape from the middle of the
25-
* basic block.
26-
*
27-
* We use the `BasicBlock.isUnreachable()` predicate to identify `BasicBlock`s which are unreachable
28-
* according to our calculated control flow graph. In practice, this can resolve expressions used in
29-
* conditions which are constant, accesses of constant values (even across function boundaries), and
30-
* operations, recursively, on such expressions. There is no attempt made to resolve conditional
31-
* expressions which are not statically constant or derived directly from statically constant variables.
32-
*
33-
* One potential problem with using `BasicBlock`s is that for template functions the `BasicBlock` is
34-
* duplicated across multiple `Function` instances, one for uninstantiated templates, and one for
35-
* each instantiation. Rather than considering each template instantiation independently, we instead
36-
* only report a `BasicBlock` in a template as unreachable, if it is unreachable in all template
37-
* instantiations (and in the uninstantiated template). This helps avoid flagging examples such as
38-
* `return 1` as dead code in this example, where `T::isVal()` is statically deducible in some
39-
* template instantiations:
40-
* ```
41-
* template <class T> int f() {
42-
* if (T::isVal()) return 1;
43-
* return 2;
44-
* }
45-
* ```
46-
*/
47-
48-
from UnreachableBasicBlock b
49-
where
50-
// None of the basic blocks are excluded
51-
not isExcluded(b.getABasicBlock(), DeadCodePackage::unreachableCodeQuery()) and
52-
// Exclude results where at least one of the basic blocks appears in a macro expansion, as
53-
// macros can easily result in unreachable blocks through no fault of the user of the macro
54-
not inMacroExpansion(b.getABasicBlock())
55-
select b, "This statement in function $@ is unreachable.", b.getPrimaryFunction() as f, f.getName()
22+
class UnreachableCodeQuery extends UnreachableCodeSharedQuery {
23+
UnreachableCodeQuery() { this = DeadCodePackage::unreachableCodeQuery() }
24+
}

cpp/autosar/src/rules/M0-1-9/DeadCode.ql

Lines changed: 3 additions & 111 deletions
Original file line numberDiff line numberDiff line change
@@ -16,116 +16,8 @@
1616

1717
import cpp
1818
import codingstandards.cpp.autosar
19-
import codingstandards.cpp.deadcode.UselessAssignments
20-
import codingstandards.cpp.deadcode.UnreachableCode
19+
import codingstandards.cpp.rules.deadcode.DeadCode
2120

22-
/*
23-
* This query finds the following kinds of dead code statement:
24-
* - A declaration of a non-static stack variable whose initializing expression is pure and that is never subsequently accessed in live code.
25-
* - A block that contain only dead statements.
26-
* - A do loop whose condition is pure, and whose body contains only dead statements.
27-
* - An if statement whose condition is pure, and whose then and else clauses (where they exist) only contain dead statements.
28-
* - A label statement to which the code never jumps.
29-
* - A while loop whose condition is pure, and whose body contains only dead statements.
30-
* - Expression statements whose expressions are pure.
31-
* - Writes to a non-static stack variable that is never subsequently read in live code.
32-
*/
33-
34-
/**
35-
* Holds if the `Stmt` `s` is either dead or unreachable.
36-
*/
37-
predicate isDeadOrUnreachableStmt(Stmt s) {
38-
isDeadStmt(s)
39-
or
40-
s.getBasicBlock() = any(UnreachableBasicBlock ubb).getABasicBlock()
21+
class MisraCppDeadCodeQuery extends DeadCodeSharedQuery {
22+
MisraCppDeadCodeQuery() { this = DeadCodePackage::deadCodeQuery() }
4123
}
42-
43-
/**
44-
* Holds if the `Stmt` `s` is dead, i.e. could be executed, but its removal would not meaningfully
45-
* affect the program.
46-
*/
47-
predicate isDeadStmt(Stmt s) {
48-
// A `DeclStmt` is dead code if:
49-
// - All the declarations are variable declarations
50-
// - None of those variables are ever accessed in non-dead code
51-
// - The initializers for each of the variables are pure
52-
exists(DeclStmt ds |
53-
ds = s and
54-
// Use forex so that we don't flag "fake" generated `DeclStmt`s (e.g. those generated by the
55-
// extractor for static_asserts) with no actual declarations
56-
forex(Declaration d | d = ds.getADeclaration() |
57-
exists(LocalScopeVariable v |
58-
d = v and
59-
v.getInitializer().getExpr().isPure() and
60-
not exists(VariableAccess va |
61-
va.getTarget() = v and
62-
not isDeadOrUnreachableStmt(va.getEnclosingStmt())
63-
)
64-
)
65-
)
66-
)
67-
or
68-
// A block that only contains dead statements.
69-
exists(BlockStmt b |
70-
b = s and
71-
forall(Stmt child | child = b.getAStmt() | isDeadStmt(child)) and
72-
// If this is a catch block, we should only report it as dead if it is the last catch block.
73-
not exists(TryStmt ts, int i |
74-
ts.getCatchClause(i) = b and
75-
i < (ts.getNumberOfCatchClauses() - 1)
76-
)
77-
)
78-
or
79-
// A do statement whose condition is pure, and whose body contains only dead statements.
80-
exists(DoStmt ds |
81-
ds = s and
82-
ds.getCondition().isPure() and
83-
isDeadOrUnreachableStmt(ds.getStmt())
84-
)
85-
or
86-
// An if statement whose condition is pure, and whose then and else clauses (where they exist) are dead or unreachable
87-
exists(IfStmt is |
88-
is = s and
89-
is.getCondition().isPure() and
90-
// Then part is either dead or unreachable
91-
isDeadOrUnreachableStmt(is.getThen()) and
92-
(exists(is.getElse()) implies isDeadOrUnreachableStmt(is.getElse()))
93-
)
94-
or
95-
// A while statement whose condition is pure, and whose body is a dead or unreachable statement
96-
exists(WhileStmt ws |
97-
ws = s and
98-
ws.getCondition().isPure() and
99-
isDeadOrUnreachableStmt(ws.getStmt())
100-
)
101-
or
102-
// An expression statement which is pure
103-
s.(ExprStmt).getExpr().isPure()
104-
or
105-
exists(SsaDefinition sd, LocalScopeVariable v |
106-
// A useless definition
107-
isUselessSsaDefinition(sd, v) and
108-
s.(ExprStmt).getExpr() = sd.getDefinition() and
109-
// The defining value is pure
110-
sd.getDefiningValue(v).isPure()
111-
)
112-
or
113-
// Any TryStmt with a dead body is dead. We ignore the catch blocks, because if the body is dead,
114-
// no exception can be thrown, and so the catch blocks are unreachable
115-
exists(TryStmt ts | s = ts and isDeadStmt(ts.getStmt()))
116-
}
117-
118-
from Stmt s
119-
where
120-
not isExcluded(s, DeadCodePackage::deadCodeQuery()) and
121-
isDeadStmt(s) and
122-
// Report only the highest level dead statement, to avoid over reporting
123-
not isDeadStmt(s.getParentStmt()) and
124-
// MISRA defines dead code as an "_executed_ statement whose removal would not affect the program
125-
// output". We therefore exclude unreachable statements as they are, by definition, not executed.
126-
not s.getBasicBlock() = any(UnreachableBasicBlock ubb).getABasicBlock() and
127-
// Exclude code generated by macros, because the code may be "live" in other instantiations
128-
not s.isAffectedByMacro() and
129-
// Exclude compiler generated statements
130-
not s.isCompilerGenerated()
131-
select s, "This statement is dead code."

cpp/autosar/test/rules/A0-1-4/UnusedParameter.qlref

Lines changed: 0 additions & 1 deletion
This file was deleted.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
cpp/common/test/rules/unusedparameter/UnusedParameter.ql

cpp/autosar/test/rules/A0-1-6/UnusedTypeDeclarations.qlref

Lines changed: 0 additions & 1 deletion
This file was deleted.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
cpp/common/test/rules/unusedtypedeclarations/UnusedTypeDeclarations.ql

cpp/autosar/test/rules/M0-1-1/UnreachableCode.qlref

Lines changed: 0 additions & 1 deletion
This file was deleted.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
cpp/common/test/rules/unreachablecode/UnreachableCode.ql

0 commit comments

Comments
 (0)