From: Alexandre Terrasa Date: Sat, 17 Oct 2015 02:40:22 +0000 (-0400) Subject: nitsaf: add flow merge on `if..else` blocks X-Git-Tag: v0.8~6^2~5 X-Git-Url: http://nitlanguage.org nitsaf: add flow merge on `if..else` blocks Signed-off-by: Alexandre Terrasa --- diff --git a/src/saf/saf_base.nit b/src/saf/saf_base.nit index 806b711..48f5cbf 100644 --- a/src/saf/saf_base.nit +++ b/src/saf/saf_base.nit @@ -131,3 +131,28 @@ redef class ANode v.outsets[self] = v.current_outset end end + +redef class AIfExpr + + # Merge flow on if .. else constructs. + redef fun accept_forward_analysis(v) do + v.enter_visit(n_expr) + var inset = v.current_inset + var outset = v.current_outset + + if n_then != null then v.enter_visit(n_then) + var then_outset = v.current_outset + + v.current_inset = inset + v.current_outset = outset + + if n_else != null then + v.enter_visit(n_else) + outset = v.merge(then_outset, v.current_outset) + else + outset = v.merge(then_outset, v.current_inset) + end + v.current_inset = inset + v.current_outset = outset + end +end diff --git a/tests/nitsaf.args b/tests/nitsaf.args index 457c2de..386bf16 100644 --- a/tests/nitsaf.args +++ b/tests/nitsaf.args @@ -1,2 +1,5 @@ --analysis reaching-defs test_saf/simple1.nit --analysis reaching-defs test_saf/simple2.nit +--analysis reaching-defs test_saf/flow_if1.nit +--analysis reaching-defs test_saf/flow_if2.nit +--analysis reaching-defs test_saf/flow_if3.nit diff --git a/tests/sav/nitsaf_args3.res b/tests/sav/nitsaf_args3.res new file mode 100644 index 0000000..14c74b4 --- /dev/null +++ b/tests/sav/nitsaf_args3.res @@ -0,0 +1,55 @@ +15: {x: 15} out of AListExprs +15: {x: 15} out of ACallExpr +15: {x: 15} out of AVardeclExpr +16: {x: 15} out of TKwvar +16: {x: 15} out of TId +16: {x: 15} out of TAssign +16: {x: 15} out of AImplicitSelfExpr +16: {x: 15} out of TId +16: {x: 15} out of AQid +16: {x: 15} out of AListExprs +16: {x: 15} out of ACallExpr +16: {x: 15} out of TId +16: {x: 15} out of AQid +16: {x: 15}, {y: 16} out of AListExprs +16: {x: 15}, {y: 16} out of ACallExpr +16: {x: 15}, {y: 16} out of AVardeclExpr +17: {x: 15}, {y: 16} out of TId +17: {x: 15}, {y: 16} out of AVarExpr +17: {x: 15}, {y: 16} out of TGt +17: {x: 15}, {y: 16} out of TId +17: {x: 15}, {y: 16} out of AVarExpr +17: {x: 15}, {y: 16} out of AGtExpr +18: {x: 15}, {y: 16} out of TId +18: {x: 15}, {y: 16} out of TAssign +18: {x: 15}, {y: 16} out of TId +18: {x: 15}, {y: 16} out of AVarExpr +18: {x: 15}, {y: 16} out of TPlus +18: {x: 18}, {y: 16} out of TInteger +18: {x: 18}, {y: 16} out of AIntegerExpr +18: {x: 18}, {y: 16} out of APlusExpr +18: {x: 18}, {y: 16} out of AVarAssignExpr +18: {x: 18}, {y: 16} out of ABlockExpr +19: {x: 15}, {y: 16} out of TKwend +19: {x: 15}, {y: 16} out of ABlockExpr +20: {x: 15}, {x: 18}, {y: 16} out of TKwvar +20: {x: 15}, {x: 18}, {y: 16} out of TId +20: {x: 15}, {x: 18}, {y: 16} out of TAssign +20: {x: 15}, {x: 18}, {y: 16} out of TId +20: {x: 15}, {x: 18}, {y: 16} out of AVarExpr +20: {x: 15}, {x: 18}, {y: 16} out of TPlus +20: {x: 15}, {x: 18}, {y: 16}, {z: 20} out of TId +20: {x: 15}, {x: 18}, {y: 16}, {z: 20} out of AVarExpr +20: {x: 15}, {x: 18}, {y: 16}, {z: 20} out of APlusExpr +20: {x: 15}, {x: 18}, {y: 16}, {z: 20} out of AVardeclExpr +21: {x: 15}, {x: 18}, {y: 16}, {z: 20} out of AImplicitSelfExpr +21: {x: 15}, {x: 18}, {y: 16}, {z: 20} out of TId +21: {x: 15}, {x: 18}, {y: 16}, {z: 20} out of AQid +21: {x: 15}, {x: 18}, {y: 16}, {z: 20} out of TId +21: {x: 15}, {x: 18}, {y: 16}, {z: 20} out of AVarExpr +21: {x: 15}, {x: 18}, {y: 16}, {z: 20} out of AListExprs +21: {x: 15}, {x: 18}, {y: 16}, {z: 20} out of ACallExpr +21: {x: 15}, {x: 18}, {y: 16}, {z: 20} out of ABlockExpr +21: {x: 15}, {x: 18}, {y: 16}, {z: 20} out of AMainMethPropdef +21: {x: 15}, {x: 18}, {y: 16}, {z: 20} out of AMainClassdef +21: {x: 15}, {x: 18}, {y: 16}, {z: 20} out of AModule diff --git a/tests/sav/nitsaf_args4.res b/tests/sav/nitsaf_args4.res new file mode 100644 index 0000000..12a2a8b --- /dev/null +++ b/tests/sav/nitsaf_args4.res @@ -0,0 +1,60 @@ +15: {x: 15} out of AListExprs +15: {x: 15} out of ACallExpr +15: {x: 15} out of AVardeclExpr +16: {x: 15} out of TKwvar +16: {x: 15} out of TId +16: {x: 15} out of TAssign +16: {x: 15} out of AImplicitSelfExpr +16: {x: 15} out of TId +16: {x: 15} out of AQid +16: {x: 15} out of AListExprs +16: {x: 15} out of ACallExpr +16: {x: 15} out of TId +16: {x: 15} out of AQid +16: {x: 15}, {y: 16} out of AListExprs +16: {x: 15}, {y: 16} out of ACallExpr +16: {x: 15}, {y: 16} out of AVardeclExpr +17: {x: 15}, {y: 16} out of TId +17: {x: 15}, {y: 16} out of AVarExpr +17: {x: 15}, {y: 16} out of TGt +17: {x: 15}, {y: 16} out of TId +17: {x: 15}, {y: 16} out of AVarExpr +17: {x: 15}, {y: 16} out of AGtExpr +18: {x: 15}, {y: 16} out of TId +18: {x: 15}, {y: 16} out of TAssign +18: {x: 15}, {y: 16} out of TId +18: {x: 15}, {y: 16} out of AVarExpr +18: {x: 15}, {y: 16} out of TPlus +18: {x: 18}, {y: 16} out of TInteger +18: {x: 18}, {y: 16} out of AIntegerExpr +18: {x: 18}, {y: 16} out of APlusExpr +18: {x: 18}, {y: 16} out of AVarAssignExpr +18: {x: 18}, {y: 16} out of ABlockExpr +20: {x: 15}, {y: 16} out of TId +20: {x: 15}, {y: 16} out of TAssign +20: {x: 15}, {y: 20} out of TId +20: {x: 15}, {y: 20} out of AVarExpr +20: {x: 15}, {y: 20} out of AVarAssignExpr +21: {x: 15}, {y: 20} out of TKwend +21: {x: 15}, {y: 20} out of ABlockExpr +22: {x: 15}, {x: 18}, {y: 16}, {y: 20} out of TKwvar +22: {x: 15}, {x: 18}, {y: 16}, {y: 20} out of TId +22: {x: 15}, {x: 18}, {y: 16}, {y: 20} out of TAssign +22: {x: 15}, {x: 18}, {y: 16}, {y: 20} out of TId +22: {x: 15}, {x: 18}, {y: 16}, {y: 20} out of AVarExpr +22: {x: 15}, {x: 18}, {y: 16}, {y: 20} out of TPlus +22: {x: 15}, {x: 18}, {y: 16}, {y: 20}, {z: 22} out of TId +22: {x: 15}, {x: 18}, {y: 16}, {y: 20}, {z: 22} out of AVarExpr +22: {x: 15}, {x: 18}, {y: 16}, {y: 20}, {z: 22} out of APlusExpr +22: {x: 15}, {x: 18}, {y: 16}, {y: 20}, {z: 22} out of AVardeclExpr +23: {x: 15}, {x: 18}, {y: 16}, {y: 20}, {z: 22} out of AImplicitSelfExpr +23: {x: 15}, {x: 18}, {y: 16}, {y: 20}, {z: 22} out of TId +23: {x: 15}, {x: 18}, {y: 16}, {y: 20}, {z: 22} out of AQid +23: {x: 15}, {x: 18}, {y: 16}, {y: 20}, {z: 22} out of TId +23: {x: 15}, {x: 18}, {y: 16}, {y: 20}, {z: 22} out of AVarExpr +23: {x: 15}, {x: 18}, {y: 16}, {y: 20}, {z: 22} out of AListExprs +23: {x: 15}, {x: 18}, {y: 16}, {y: 20}, {z: 22} out of ACallExpr +23: {x: 15}, {x: 18}, {y: 16}, {y: 20}, {z: 22} out of ABlockExpr +23: {x: 15}, {x: 18}, {y: 16}, {y: 20}, {z: 22} out of AMainMethPropdef +23: {x: 15}, {x: 18}, {y: 16}, {y: 20}, {z: 22} out of AMainClassdef +23: {x: 15}, {x: 18}, {y: 16}, {y: 20}, {z: 22} out of AModule diff --git a/tests/sav/nitsaf_args5.res b/tests/sav/nitsaf_args5.res new file mode 100644 index 0000000..c208db9 --- /dev/null +++ b/tests/sav/nitsaf_args5.res @@ -0,0 +1,83 @@ +15: {x: 15} out of AListExprs +15: {x: 15} out of ACallExpr +15: {x: 15} out of AVardeclExpr +16: {x: 15} out of TKwvar +16: {x: 15} out of TId +16: {x: 15} out of TAssign +16: {x: 15} out of AImplicitSelfExpr +16: {x: 15} out of TId +16: {x: 15} out of AQid +16: {x: 15} out of AListExprs +16: {x: 15} out of ACallExpr +16: {x: 15} out of TId +16: {x: 15} out of AQid +16: {x: 15}, {y: 16} out of AListExprs +16: {x: 15}, {y: 16} out of ACallExpr +16: {x: 15}, {y: 16} out of AVardeclExpr +17: {x: 15}, {y: 16} out of TId +17: {x: 15}, {y: 16} out of AVarExpr +17: {x: 15}, {y: 16} out of TGt +17: {x: 15}, {y: 16} out of TId +17: {x: 15}, {y: 16} out of AVarExpr +17: {x: 15}, {y: 16} out of AGtExpr +18: {x: 15}, {y: 16} out of TId +18: {x: 15}, {y: 16} out of AVarExpr +18: {x: 15}, {y: 16} out of TEq +18: {x: 15}, {y: 16} out of TInteger +18: {x: 15}, {y: 16} out of AIntegerExpr +18: {x: 15}, {y: 16} out of AEqExpr +19: {x: 15}, {y: 16} out of TId +19: {x: 15}, {y: 16} out of TAssign +19: {x: 19}, {y: 16} out of TInteger +19: {x: 19}, {y: 16} out of AIntegerExpr +19: {x: 19}, {y: 16} out of AVarAssignExpr +19: {x: 19}, {y: 16} out of ABlockExpr +21: {x: 15}, {y: 16} out of TId +21: {x: 15}, {y: 16} out of TAssign +21: {x: 15}, {y: 16} out of TId +21: {x: 15}, {y: 16} out of AVarExpr +21: {x: 15}, {y: 16} out of TPlus +21: {x: 21}, {y: 16} out of TInteger +21: {x: 21}, {y: 16} out of AIntegerExpr +21: {x: 21}, {y: 16} out of APlusExpr +21: {x: 21}, {y: 16} out of AVarAssignExpr +22: {x: 21}, {y: 16} out of TKwend +22: {x: 21}, {y: 16} out of ABlockExpr +22: {x: 19}, {x: 21}, {y: 16} out of ABlockExpr +24: {x: 15}, {y: 16} out of TId +24: {x: 15}, {y: 16} out of AVarExpr +24: {x: 15}, {y: 16} out of TEq +24: {x: 15}, {y: 16} out of TInteger +24: {x: 15}, {y: 16} out of AIntegerExpr +24: {x: 15}, {y: 16} out of AEqExpr +25: {x: 15}, {y: 16} out of TId +25: {x: 15}, {y: 16} out of TAssign +25: {x: 15}, {y: 25} out of TId +25: {x: 15}, {y: 25} out of AVarExpr +25: {x: 15}, {y: 25} out of AVarAssignExpr +25: {x: 15}, {y: 25} out of ABlockExpr +26: {x: 15}, {y: 16} out of TKwend +26: {x: 15}, {y: 16} out of ABlockExpr +27: {x: 15}, {y: 16}, {y: 25} out of TKwend +27: {x: 15}, {y: 16}, {y: 25} out of ABlockExpr +28: {x: 15}, {x: 19}, {x: 21}, {y: 16}, {y: 25} out of TKwvar +28: {x: 15}, {x: 19}, {x: 21}, {y: 16}, {y: 25} out of TId +28: {x: 15}, {x: 19}, {x: 21}, {y: 16}, {y: 25} out of TAssign +28: {x: 15}, {x: 19}, {x: 21}, {y: 16}, {y: 25} out of TId +28: {x: 15}, {x: 19}, {x: 21}, {y: 16}, {y: 25} out of AVarExpr +28: {x: 15}, {x: 19}, {x: 21}, {y: 16}, {y: 25} out of TPlus +28: {x: 15}, {x: 19}, {x: 21}, {y: 16}, {y: 25}, {z: 28} out of TId +28: {x: 15}, {x: 19}, {x: 21}, {y: 16}, {y: 25}, {z: 28} out of AVarExpr +28: {x: 15}, {x: 19}, {x: 21}, {y: 16}, {y: 25}, {z: 28} out of APlusExpr +28: {x: 15}, {x: 19}, {x: 21}, {y: 16}, {y: 25}, {z: 28} out of AVardeclExpr +29: {x: 15}, {x: 19}, {x: 21}, {y: 16}, {y: 25}, {z: 28} out of AImplicitSelfExpr +29: {x: 15}, {x: 19}, {x: 21}, {y: 16}, {y: 25}, {z: 28} out of TId +29: {x: 15}, {x: 19}, {x: 21}, {y: 16}, {y: 25}, {z: 28} out of AQid +29: {x: 15}, {x: 19}, {x: 21}, {y: 16}, {y: 25}, {z: 28} out of TId +29: {x: 15}, {x: 19}, {x: 21}, {y: 16}, {y: 25}, {z: 28} out of AVarExpr +29: {x: 15}, {x: 19}, {x: 21}, {y: 16}, {y: 25}, {z: 28} out of AListExprs +29: {x: 15}, {x: 19}, {x: 21}, {y: 16}, {y: 25}, {z: 28} out of ACallExpr +29: {x: 15}, {x: 19}, {x: 21}, {y: 16}, {y: 25}, {z: 28} out of ABlockExpr +29: {x: 15}, {x: 19}, {x: 21}, {y: 16}, {y: 25}, {z: 28} out of AMainMethPropdef +29: {x: 15}, {x: 19}, {x: 21}, {y: 16}, {y: 25}, {z: 28} out of AMainClassdef +29: {x: 15}, {x: 19}, {x: 21}, {y: 16}, {y: 25}, {z: 28} out of AModule diff --git a/tests/test_saf/flow_if1.nit b/tests/test_saf/flow_if1.nit new file mode 100644 index 0000000..982329b --- /dev/null +++ b/tests/test_saf/flow_if1.nit @@ -0,0 +1,21 @@ +# 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. + +var x = gets.to_i +var y = gets.to_i +if x > y then + x = x + 1 +end +var z = x + y +print z diff --git a/tests/test_saf/flow_if2.nit b/tests/test_saf/flow_if2.nit new file mode 100644 index 0000000..3cfbcec --- /dev/null +++ b/tests/test_saf/flow_if2.nit @@ -0,0 +1,23 @@ +# 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. + +var x = gets.to_i +var y = gets.to_i +if x > y then + x = x + 1 +else + y = x +end +var z = x + y +print z diff --git a/tests/test_saf/flow_if3.nit b/tests/test_saf/flow_if3.nit new file mode 100644 index 0000000..3abd931 --- /dev/null +++ b/tests/test_saf/flow_if3.nit @@ -0,0 +1,29 @@ +# 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. + +var x = gets.to_i +var y = gets.to_i +if x > y then + if y == 0 then + x = 2 + else + x = x + 1 + end +else + if x == 0 then + y = x + end +end +var z = x + y +print z