1212 */
1313
1414import cpp
15+ import codingstandards.cpp.alertreporting.HoldsForAllInstances
1516import codingstandards.cpp.Customizations
1617import codingstandards.cpp.Exclusions
1718import codingstandards.cpp.deadcode.UselessAssignments
@@ -31,10 +32,6 @@ predicate isDeadOrUnreachableStmt(Stmt s) {
3132 s .getBasicBlock ( ) = any ( UnreachableBasicBlock ubb ) .getABasicBlock ( )
3233}
3334
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- */
3835predicate isDeadStmt ( Stmt s ) {
3936 // A `DeclStmt` is dead code if:
4037 // - All the declarations are variable declarations
@@ -108,17 +105,33 @@ predicate isDeadStmt(Stmt s) {
108105 exists ( TryStmt ts | s = ts and isDeadStmt ( ts .getStmt ( ) ) )
109106}
110107
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
113129 message = "This statement is dead code." and
114- isDeadStmt ( s ) and
115130 // 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+ )
124137}
0 commit comments