@@ -75,8 +75,10 @@ predicate succExit(CfgScope scope, Ast last, Completion c) { scope.exit(last, c)
7575
7676/** Defines the CFG by dispatch on the various AST types. */
7777module Trees {
78- class ScriptBlockTree extends PreOrderTree instanceof ScriptBlock {
79- final override predicate last ( AstNode last , Completion c ) {
78+ abstract class ScriptBlockTree extends ControlFlowTree instanceof ScriptBlock {
79+ abstract predicate succEntry ( AstNode n , Completion c ) ;
80+
81+ override predicate last ( AstNode last , Completion c ) {
8082 last ( super .getEndBlock ( ) , last , c )
8183 or
8284 not exists ( super .getEndBlock ( ) ) and
@@ -89,43 +91,58 @@ module Trees {
8991 not exists ( super .getEndBlock ( ) ) and
9092 not exists ( super .getProcessBlock ( ) ) and
9193 not exists ( super .getBeginBlock ( ) ) and
92- last = this and
93- completionIsSimple ( c )
94- }
95-
96- final override predicate propagatesAbnormal ( AstNode child ) {
97- child = [ super .getBeginBlock ( ) , super .getProcessBlock ( ) , super .getEndBlock ( ) ]
94+ last ( super .getParamBlock ( ) , last , c )
95+ or
96+ not exists ( super .getEndBlock ( ) ) and
97+ not exists ( super .getProcessBlock ( ) ) and
98+ not exists ( super .getBeginBlock ( ) ) and
99+ not exists ( super .getParamBlock ( ) ) and
100+ // No blocks at all. We end where we started
101+ this .succEntry ( last , c )
98102 }
99103
100- final override predicate succ ( AstNode pred , AstNode succ , Completion c ) {
101- pred = this and
104+ override predicate succ ( AstNode pred , AstNode succ , Completion c ) {
105+ this . succEntry ( pred , c ) and
102106 (
107+ first ( super .getParamBlock ( ) , succ )
108+ or
109+ not exists ( super .getParamBlock ( ) ) and
103110 first ( super .getBeginBlock ( ) , succ )
104111 or
112+ not exists ( super .getParamBlock ( ) ) and
105113 not exists ( super .getBeginBlock ( ) ) and
106114 first ( super .getProcessBlock ( ) , succ )
107115 or
116+ not exists ( super .getParamBlock ( ) ) and
108117 not exists ( super .getBeginBlock ( ) ) and
109118 not exists ( super .getProcessBlock ( ) ) and
110119 first ( super .getEndBlock ( ) , succ )
111- ) and
112- completionIsSimple ( c )
120+ )
113121 or
114- last ( super .getBeginBlock ( ) , pred , c ) and
115- c instanceof NormalCompletion and
122+ last ( super .getParamBlock ( ) , pred , c ) and
123+ completionIsNormal ( c ) and
116124 (
125+ first ( super .getBeginBlock ( ) , succ )
126+ or
127+ not exists ( super .getBeginBlock ( ) ) and
117128 first ( super .getProcessBlock ( ) , succ )
118129 or
130+ not exists ( super .getBeginBlock ( ) ) and
119131 not exists ( super .getProcessBlock ( ) ) and
120132 first ( super .getEndBlock ( ) , succ )
133+ )
134+ or
135+ last ( super .getBeginBlock ( ) , pred , c ) and
136+ completionIsNormal ( c ) and
137+ (
138+ first ( super .getProcessBlock ( ) , succ )
121139 or
122140 not exists ( super .getProcessBlock ( ) ) and
123- not exists ( super .getEndBlock ( ) ) and
124- succ = this
141+ first ( super .getEndBlock ( ) , succ )
125142 )
126143 or
127144 last ( super .getProcessBlock ( ) , pred , c ) and
128- c instanceof NormalCompletion and
145+ completionIsNormal ( c ) and
129146 (
130147 // If we process multiple items we will loop back to the process block
131148 first ( super .getProcessBlock ( ) , succ )
@@ -134,6 +151,19 @@ module Trees {
134151 first ( super .getEndBlock ( ) , succ )
135152 )
136153 }
154+
155+ final override predicate propagatesAbnormal ( AstNode child ) {
156+ child = super .getParamBlock ( ) or
157+ child = super .getBeginBlock ( ) or
158+ child = super .getProcessBlock ( ) or
159+ child = super .getEndBlock ( )
160+ }
161+ }
162+
163+ class TopLevelScriptBlockTree extends PreOrderTree , ScriptBlockTree {
164+ TopLevelScriptBlockTree ( ) { this .( ScriptBlock ) .isTopLevel ( ) }
165+
166+ final override predicate succEntry ( Ast n , Completion c ) { n = this and completionIsSimple ( c ) }
137167 }
138168
139169 class NamedBlockTree extends StandardPostOrderTree instanceof NamedBlock {
0 commit comments