8080 */
8181
8282private import cpp
83- private import semmle.code.cpp.controlflow.internal.SyntheticDestructorCalls
8483
8584/**
8685 * A control-flow node. This class exists to provide a shorter name than
@@ -115,8 +114,7 @@ private class Node extends ControlFlowNodeBase {
115114 */
116115private predicate excludeNodeAndNodesBelow ( Expr e ) {
117116 not exists ( e .getParent ( ) ) and
118- not e instanceof DestructorCall and
119- not e instanceof SyntheticDestructorCall // Workaround for CPP-320
117+ not e instanceof DestructorCall
120118 or
121119 // Constructor init lists should be evaluated, and we can change this in
122120 // the future, but it would mean that a `Function` entry point is not
@@ -983,36 +981,10 @@ private predicate subEdgeIncludingDestructors(Pos p1, Node n1, Node n2, Pos p2)
983981 // called, connect the "before destructors" node directly to the "after
984982 // destructors" node. For performance, only do this when the nodes exist.
985983 exists ( Pos afterDtors | afterDtors .isAfterDestructors ( ) | subEdge ( afterDtors , n1 , _, _) ) and
986- not exists ( getDestructorCallAfterNode ( n1 , 0 ) ) and
987984 not synthetic_destructor_call ( n1 , 0 , _) and
988985 p1 .nodeBeforeDestructors ( n1 , n1 ) and
989986 p2 .nodeAfterDestructors ( n2 , n1 )
990987 or
991- exists ( Node n |
992- // before destructors -> access(0)
993- p1 .nodeBeforeDestructors ( n1 , n ) and
994- p2 .nodeAt ( n2 , getDestructorCallAfterNode ( n , 0 ) .getAccess ( ) )
995- or
996- // access(i) -> call(i)
997- exists ( int i |
998- p1 .nodeAt ( n1 , getDestructorCallAfterNode ( n , i ) .getAccess ( ) ) and
999- p2 .nodeAt ( n2 , getDestructorCallAfterNode ( n , i ) )
1000- )
1001- or
1002- // call(i) -> access(i+1)
1003- exists ( int i |
1004- p1 .nodeAt ( n1 , getDestructorCallAfterNode ( n , i ) ) and
1005- p2 .nodeAt ( n2 , getDestructorCallAfterNode ( n , i + 1 ) .getAccess ( ) )
1006- )
1007- or
1008- // call(max) -> after destructors end
1009- exists ( int maxCallIndex |
1010- maxCallIndex = max ( int i | exists ( getDestructorCallAfterNode ( n , i ) ) ) and
1011- p1 .nodeAt ( n1 , getDestructorCallAfterNode ( n , maxCallIndex ) ) and
1012- p2 .nodeAfterDestructors ( n2 , n )
1013- )
1014- )
1015- or
1016988 exists ( Node n |
1017989 // before destructors -> access(max)
1018990 exists ( int maxCallIndex |
@@ -1032,6 +1004,34 @@ private predicate subEdgeIncludingDestructors(Pos p1, Node n1, Node n2, Pos p2)
10321004 )
10331005}
10341006
1007+ /**
1008+ * Gets the `index`'th synthetic destructor call that should follow `node`. The
1009+ * exact placement of that call in the CFG depends on the type of `node` as
1010+ * follows:
1011+ *
1012+ * - `Block`: after ordinary control flow falls off the end of the block
1013+ * without jumps or exceptions.
1014+ * - `ReturnStmt`: After the statement itself or after its operand (if
1015+ * present).
1016+ * - `ThrowExpr`: After the `throw` expression or after its operand (if
1017+ * present).
1018+ * - `JumpStmt` (`BreakStmt`, `ContinueStmt`, `GotoStmt`): after the statement.
1019+ * - A `ForStmt`, `WhileStmt`, `SwitchStmt`, or `IfStmt`: after control flow
1020+ * falls off the end of the statement without jumping. Destruction can occur
1021+ * here for `for`-loops that have an initializer (`for (C x = a; ...; ...)`)
1022+ * and for statements whose condition is a `ConditionDeclExpr`
1023+ * (`if (C x = a)`).
1024+ * - The `getUpdate()` of a `ForStmt`: after the `getUpdate()` expression. This
1025+ * can happen when the condition is a `ConditionDeclExpr`
1026+ * - `Handler`: On the edge out of the `Handler` for the case where the
1027+ * exception was not matched and is propagated to the next handler or
1028+ * function exit point.
1029+ * - `MicrosoftTryExceptStmt`: After the false-edge out of the `e` in
1030+ * `__except(e)`, before propagating the exception up to the next handler or
1031+ * function exit point.
1032+ * - `MicrosoftTryFinallyStmt`: On the edge following the `__finally` block for
1033+ * the case where an exception was thrown and needs to be propagated.
1034+ */
10351035DestructorCall getSynthesisedDestructorCallAfterNode ( Node n , int i ) {
10361036 synthetic_destructor_call ( n , i , result )
10371037}
0 commit comments