12
12
*/
13
13
14
14
import cpp
15
+ import codingstandards.cpp.alertreporting.HoldsForAllInstances
15
16
import codingstandards.cpp.Customizations
16
17
import codingstandards.cpp.Exclusions
17
18
import codingstandards.cpp.deadcode.UselessAssignments
@@ -31,10 +32,6 @@ predicate isDeadOrUnreachableStmt(Stmt s) {
31
32
s .getBasicBlock ( ) = any ( UnreachableBasicBlock ubb ) .getABasicBlock ( )
32
33
}
33
34
34
- /**
35
- * Holds if the `Stmt` `s` is dead, i.e. could be executed, but its removal would not meaningfully
36
- * affect the program.
37
- */
38
35
predicate isDeadStmt ( Stmt s ) {
39
36
// A `DeclStmt` is dead code if:
40
37
// - All the declarations are variable declarations
@@ -108,17 +105,33 @@ predicate isDeadStmt(Stmt s) {
108
105
exists ( TryStmt ts | s = ts and isDeadStmt ( ts .getStmt ( ) ) )
109
106
}
110
107
111
- query predicate problems ( Stmt s , string message ) {
112
- not isExcluded ( s , getQuery ( ) ) and
108
+ /**
109
+ * Holds if the `Stmt` `s` is dead, i.e. could be executed, but its removal would not meaningfully
110
+ * affect the program.
111
+ */
112
+ class DeadStmtInstance extends Stmt {
113
+ DeadStmtInstance ( ) {
114
+ isDeadStmt ( this ) and
115
+ // Exclude compiler generated statements
116
+ not this .isCompilerGenerated ( ) and
117
+ // Exclude code fully generated by macros, because the code may be "live" in other expansions
118
+ not this .isInMacroExpansion ( ) and
119
+ // MISRA defines dead code as an "_executed_ statement whose removal would not affect the program
120
+ // output". We therefore exclude unreachable statements as they are, by definition, not executed.
121
+ not this .getBasicBlock ( ) = any ( UnreachableBasicBlock ubb ) .getABasicBlock ( )
122
+ }
123
+ }
124
+
125
+ class DeadStmt = HoldsForAllInstances< DeadStmtInstance > :: LogicalResultStmt ;
126
+
127
+ query predicate problems ( DeadStmt s , string message ) {
128
+ not isExcluded ( s .getAStmtInstance ( ) , getQuery ( ) ) and
113
129
message = "This statement is dead code." and
114
- isDeadStmt ( s ) and
115
130
// Report only the highest level dead statement, to avoid over reporting
116
- not isDeadStmt ( s .getParentStmt ( ) ) and
117
- // MISRA defines dead code as an "_executed_ statement whose removal would not affect the program
118
- // output". We therefore exclude unreachable statements as they are, by definition, not executed.
119
- not s .getBasicBlock ( ) = any ( UnreachableBasicBlock ubb ) .getABasicBlock ( ) and
120
- // Exclude code fully generated by macros, because the code may be "live" in other expansions
121
- not s .isInMacroExpansion ( ) and
122
- // Exclude compiler generated statements
123
- not s .isCompilerGenerated ( )
131
+ not exists ( DeadStmt parent |
132
+ // All instances must share a dead statement parent for us to report the parent instead
133
+ forall ( Stmt instance | instance = s .getAStmtInstance ( ) |
134
+ parent .getAStmtInstance ( ) = instance .getParentStmt ( )
135
+ )
136
+ )
124
137
}
0 commit comments