nitsaf: add flow merge on `if..else` blocks
authorAlexandre Terrasa <alexandre@moz-code.org>
Sat, 17 Oct 2015 02:40:22 +0000 (22:40 -0400)
committerAlexandre Terrasa <alexandre@moz-code.org>
Sat, 19 Dec 2015 08:40:58 +0000 (03:40 -0500)
Signed-off-by: Alexandre Terrasa <alexandre@moz-code.org>

src/saf/saf_base.nit
tests/nitsaf.args
tests/sav/nitsaf_args3.res [new file with mode: 0644]
tests/sav/nitsaf_args4.res [new file with mode: 0644]
tests/sav/nitsaf_args5.res [new file with mode: 0644]
tests/test_saf/flow_if1.nit [new file with mode: 0644]
tests/test_saf/flow_if2.nit [new file with mode: 0644]
tests/test_saf/flow_if3.nit [new file with mode: 0644]

index 806b711..48f5cbf 100644 (file)
@@ -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
index 457c2de..386bf16 100644 (file)
@@ -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 (file)
index 0000000..14c74b4
--- /dev/null
@@ -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 (file)
index 0000000..12a2a8b
--- /dev/null
@@ -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 (file)
index 0000000..c208db9
--- /dev/null
@@ -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 (file)
index 0000000..982329b
--- /dev/null
@@ -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 (file)
index 0000000..3cfbcec
--- /dev/null
@@ -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 (file)
index 0000000..3abd931
--- /dev/null
@@ -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