# New initial flows are empty (conservative analysis).
redef fun new_initial_flow do return new FlowHashSet[VarDef]
+ # New initial flows for methods contains the parameters.
+ redef fun new_initial_method_flow(n) do
+ var flow = new_initial_flow
+ var n_signature = n.n_signature
+ if n_signature == null then return flow
+ for n_param in n_signature.n_params do
+ var variable = n_param.variable
+ if variable == null then continue
+ flow.add(new VarDef(variable, n_param.location))
+ end
+ return flow
+ end
+
# Perform set union (used for **some path** analysis).
redef fun merge(s1, s2) do return s1.flow_union(s2)
# implementation of this method is the responsability the subclass.
fun new_initial_flow: FLOW is abstract
+ # Initial flow set to use within methods.
+ #
+ # Returns `new_initial_flow` by default.
+ # Redefine this method to inject things in the inset like parameters from
+ # the signature.
+ fun new_initial_method_flow(v: AMethPropdef): FLOW do return new_initial_flow
+
# The merge operation on sets for confluence.
#
# Depends on the analysis performed.
accept_loop_forward_analysis(v)
end
end
+
+redef class AMethPropdef
+ redef fun accept_forward_analysis(v) do
+ v.current_inset = v.new_initial_method_flow(self)
+ v.current_outset = v.current_inset.clone
+ v.insets[self] = v.current_inset
+ visit_all(v)
+ v.outsets[self] = v.current_outset
+ end
+end
--analysis reaching-defs test_saf/flow_loop1.nit
--analysis reaching-defs test_saf/flow_loop2.nit
--analysis reaching-defs test_saf/flow_loop3.nit
+--analysis reaching-defs test_saf/flow_fun1.nit
+--analysis reaching-defs test_saf/flow_fun2.nit
--- /dev/null
+15: {a: 15}, {b: 15} out of APublicVisibility
+15: {a: 15}, {b: 15} out of TKwmeth
+15: {a: 15}, {b: 15} out of TId
+15: {a: 15}, {b: 15} out of AIdMethid
+15: {a: 15}, {b: 15} out of TOpar
+15: {a: 15}, {b: 15} out of TId
+15: {a: 15}, {b: 15} out of AParam
+15: {a: 15}, {b: 15} out of TId
+15: {a: 15}, {b: 15} out of TClassid
+15: {a: 15}, {b: 15} out of AQclassid
+15: {a: 15}, {b: 15} out of AType
+15: {a: 15}, {b: 15} out of AParam
+15: {a: 15}, {b: 15} out of TCpar
+15: {a: 15}, {b: 15} out of TClassid
+15: {a: 15}, {b: 15} out of AQclassid
+15: {a: 15}, {b: 15} out of AType
+15: {a: 15}, {b: 15} out of ASignature
+15: {a: 15}, {b: 15} out of TKwdo
+16: {a: 15}, {b: 15} out of TId
+16: {a: 15}, {b: 15} out of AVarExpr
+16: {a: 15}, {b: 15} out of TEq
+16: {a: 15}, {b: 15} out of TId
+16: {a: 15}, {b: 15} out of AVarExpr
+16: {a: 15}, {b: 15} out of AEqExpr
+17: {a: 15}, {b: 15} out of TKwvar
+17: {a: 15}, {b: 15} out of TId
+17: {a: 15}, {b: 15} out of TAssign
+17: {a: 15}, {b: 15}, {c: 17} out of TInteger
+17: {a: 15}, {b: 15}, {c: 17} out of AIntegerExpr
+17: {a: 15}, {b: 15}, {c: 17} out of AVardeclExpr
+18: {a: 15}, {b: 15}, {c: 17} out of TId
+18: {a: 15}, {b: 15}, {c: 17} out of TAssign
+18: {a: 15}, {b: 18}, {c: 17} out of TId
+18: {a: 15}, {b: 18}, {c: 17} out of AVarExpr
+18: {a: 15}, {b: 18}, {c: 17} out of AVarAssignExpr
+18: {a: 15}, {b: 18}, {c: 17} out of ABlockExpr
+19: {a: 15}, {b: 15} out of TKwend
+19: {a: 15}, {b: 15} out of ABlockExpr
+20: {a: 15}, {b: 15}, {b: 18}, {c: 17} out of TKwreturn
+20: {a: 15}, {b: 15}, {b: 18}, {c: 17} out of TId
+20: {a: 15}, {b: 15}, {b: 18}, {c: 17} out of AVarExpr
+20: {a: 15}, {b: 15}, {b: 18}, {c: 17} out of AReturnExpr
+21: {a: 15}, {b: 15}, {b: 18}, {c: 17} out of TKwend
+21: {a: 15}, {b: 15}, {b: 18}, {c: 17} out of ABlockExpr
+21: {a: 15}, {b: 15}, {b: 18}, {c: 17} out of AMethPropdef
+21: {a: 15}, {b: 15}, {b: 18}, {c: 17} out of ATopClassdef
+23: {i: 23} out of AListExprs
+23: {i: 23} out of ACallExpr
+23: {i: 23} out of AVardeclExpr
+24: {i: 23} out of TKwvar
+24: {i: 23} out of TId
+24: {i: 23} out of TAssign
+24: {i: 23} out of AImplicitSelfExpr
+24: {i: 23} out of TId
+24: {i: 23} out of AQid
+24: {i: 23} out of AListExprs
+24: {i: 23} out of ACallExpr
+24: {i: 23} out of TId
+24: {i: 23} out of AQid
+24: {i: 23}, {j: 24} out of AListExprs
+24: {i: 23}, {j: 24} out of ACallExpr
+24: {i: 23}, {j: 24} out of AVardeclExpr
+25: {i: 23}, {j: 24} out of TKwvar
+25: {i: 23}, {j: 24} out of TId
+25: {i: 23}, {j: 24} out of TAssign
+25: {i: 23}, {j: 24} out of AImplicitSelfExpr
+25: {i: 23}, {j: 24} out of TId
+25: {i: 23}, {j: 24} out of AQid
+25: {i: 23}, {j: 24} out of TOpar
+25: {i: 23}, {j: 24} out of TId
+25: {i: 23}, {j: 24} out of AVarExpr
+25: {i: 23}, {j: 24} out of TId
+25: {i: 23}, {j: 24} out of AVarExpr
+25: {i: 23}, {j: 24}, {z: 25} out of TCpar
+25: {i: 23}, {j: 24}, {z: 25} out of AParExprs
+25: {i: 23}, {j: 24}, {z: 25} out of ACallExpr
+25: {i: 23}, {j: 24}, {z: 25} out of AVardeclExpr
+26: {i: 23}, {j: 24}, {z: 25} out of AImplicitSelfExpr
+26: {i: 23}, {j: 24}, {z: 25} out of TId
+26: {i: 23}, {j: 24}, {z: 25} out of AQid
+26: {i: 23}, {j: 24}, {z: 25} out of TId
+26: {i: 23}, {j: 24}, {z: 25} out of AVarExpr
+26: {i: 23}, {j: 24}, {z: 25} out of AListExprs
+26: {i: 23}, {j: 24}, {z: 25} out of ACallExpr
+26: {i: 23}, {j: 24}, {z: 25} out of ABlockExpr
+26: {i: 23}, {j: 24}, {z: 25} out of AMainMethPropdef
+26: {i: 23}, {j: 24}, {z: 25} out of AMainClassdef
+26: {i: 23}, {j: 24}, {z: 25} out of AModule
--- /dev/null
+16: {a: 16} out of TInteger
+16: {a: 16} out of AIntegerExpr
+16: {a: 16} out of AVardeclExpr
+17: {a: 16} out of TId
+17: {a: 16} out of TAssign
+17: {a: 17} out of TInteger
+17: {a: 17} out of AIntegerExpr
+17: {a: 17} out of AVarAssignExpr
+18: {a: 17} out of AImplicitSelfExpr
+18: {a: 17} out of TId
+18: {a: 17} out of AQid
+18: {a: 17} out of TId
+18: {a: 17} out of AVarExpr
+18: {a: 17} out of AListExprs
+18: {a: 17} out of ACallExpr
+19: {a: 17} out of TKwend
+19: {a: 17} out of ABlockExpr
+19: {a: 17} out of AMethPropdef
+19: {a: 17} out of ATopClassdef
+21: {a: 21}, {b: 21} out of APublicVisibility
+21: {a: 21}, {b: 21} out of TKwmeth
+21: {a: 21}, {b: 21} out of TId
+21: {a: 21}, {b: 21} out of AIdMethid
+21: {a: 21}, {b: 21} out of TOpar
+21: {a: 21}, {b: 21} out of TId
+21: {a: 21}, {b: 21} out of AParam
+21: {a: 21}, {b: 21} out of TId
+21: {a: 21}, {b: 21} out of TClassid
+21: {a: 21}, {b: 21} out of AQclassid
+21: {a: 21}, {b: 21} out of AType
+21: {a: 21}, {b: 21} out of AParam
+21: {a: 21}, {b: 21} out of TCpar
+21: {a: 21}, {b: 21} out of ASignature
+21: {a: 21}, {b: 21} out of TKwdo
+22: {a: 21}, {b: 21} out of TId
+22: {a: 21}, {b: 21} out of AVarExpr
+22: {a: 21}, {b: 21} out of TEq
+22: {a: 21}, {b: 21} out of TId
+22: {a: 21}, {b: 21} out of AVarExpr
+22: {a: 21}, {b: 21} out of AEqExpr
+23: {a: 21}, {b: 21} out of TKwvar
+23: {a: 21}, {b: 21} out of TId
+23: {a: 21}, {b: 21} out of TAssign
+23: {a: 21}, {b: 21}, {c: 23} out of TInteger
+23: {a: 21}, {b: 21}, {c: 23} out of AIntegerExpr
+23: {a: 21}, {b: 21}, {c: 23} out of AVardeclExpr
+24: {a: 21}, {b: 21}, {c: 23} out of TId
+24: {a: 21}, {b: 21}, {c: 23} out of TAssign
+24: {a: 21}, {b: 24}, {c: 23} out of TId
+24: {a: 21}, {b: 24}, {c: 23} out of AVarExpr
+24: {a: 21}, {b: 24}, {c: 23} out of AVarAssignExpr
+24: {a: 21}, {b: 24}, {c: 23} out of ABlockExpr
+25: {a: 21}, {b: 21} out of TKwend
+25: {a: 21}, {b: 21} out of ABlockExpr
+26: {a: 21}, {b: 21}, {b: 24}, {c: 23} out of AImplicitSelfExpr
+26: {a: 21}, {b: 21}, {b: 24}, {c: 23} out of TId
+26: {a: 21}, {b: 21}, {b: 24}, {c: 23} out of AQid
+26: {a: 21}, {b: 21}, {b: 24}, {c: 23} out of TId
+26: {a: 21}, {b: 21}, {b: 24}, {c: 23} out of AVarExpr
+26: {a: 21}, {b: 21}, {b: 24}, {c: 23} out of AListExprs
+26: {a: 21}, {b: 21}, {b: 24}, {c: 23} out of ACallExpr
+27: {a: 21}, {b: 21}, {b: 24}, {c: 23} out of TKwend
+27: {a: 21}, {b: 21}, {b: 24}, {c: 23} out of ABlockExpr
+27: {a: 21}, {b: 21}, {b: 24}, {c: 23} out of AMethPropdef
+27: {a: 21}, {b: 21}, {b: 24}, {c: 23} out of ATopClassdef
+32: {z: 32} out of AListExprs
+32: {z: 32} out of ACallExpr
+32: {z: 32} out of AVardeclExpr
+33: {z: 32} out of AImplicitSelfExpr
+33: {z: 32} out of TId
+33: {z: 32} out of AQid
+33: {z: 32} out of TId
+33: {z: 32} out of AVarExpr
+33: {z: 32} out of AListExprs
+33: {z: 32} out of ACallExpr
+33: {z: 32} out of ABlockExpr
+33: {z: 32} out of AMainMethPropdef
+33: {z: 32} out of AMainClassdef
+33: {z: 32} out of AModule
--- /dev/null
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+fun foo do
+ var a = 1
+ a = 2
+ print a
+end
+
+fun bar(a, b: Int) do
+ if a == b then
+ var c = 0
+ b = c
+ end
+ print b
+end
+
+foo
+bar(1, 2)
+
+var z = gets.to_i
+print z
--- /dev/null
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+fun bar(a, b: Int): Int do
+ if a == b then
+ var c = 0
+ b = c
+ end
+ return a
+end
+
+var i = gets.to_i
+var j = gets.to_i
+var z = bar(i, j)
+print z