4
4
from decompiler .pipeline .controlflowanalysis .readability_based_refinement import (
5
5
ForLoopVariableRenamer ,
6
6
ReadabilityBasedRefinement ,
7
+ WhileLoopReplacer ,
7
8
WhileLoopVariableRenamer ,
8
9
_find_continuation_instruction ,
9
10
_has_deep_requirement ,
19
20
Call ,
20
21
Condition ,
21
22
Constant ,
23
+ Continue ,
22
24
ImportedFunctionSymbol ,
23
25
ListOperation ,
24
26
OperationType ,
@@ -2077,3 +2079,114 @@ def test_declaration_listop(self, ast_call_for_loop):
2077
2079
for node in ast_call_for_loop :
2078
2080
if isinstance (node , ForLoopNode ):
2079
2081
assert node .declaration .destination .operands [0 ].name == "i"
2082
+
2083
+ def test_skip_for_loop_recovery_if_continue_in_while (self ):
2084
+ """
2085
+ a = 0
2086
+ while(a < 10) {
2087
+ if(a == 2) {
2088
+ a = a + 2
2089
+ continue
2090
+ }
2091
+ a = a + 1
2092
+ }
2093
+ """
2094
+ true_value = LogicCondition .initialize_true (context := LogicCondition .generate_new_context ())
2095
+ ast = AbstractSyntaxTree (
2096
+ root := SeqNode (true_value ),
2097
+ condition_map = {
2098
+ logic_cond ("x1" , context ): Condition (OperationType .less , [Variable ("a" ), Constant (10 )]),
2099
+ logic_cond ("x2" , context ): Condition (OperationType .equal , [Variable ("a" ), Constant (2 )])
2100
+ }
2101
+ )
2102
+
2103
+ true_branch = ast ._add_code_node (
2104
+ [
2105
+ Assignment (Variable ("a" ), BinaryOperation (OperationType .plus , [Variable ("a" ), Constant (2 )])),
2106
+ Continue ()
2107
+ ]
2108
+ )
2109
+ if_condition = ast ._add_condition_node_with (logic_cond ("x2" , context ), true_branch )
2110
+
2111
+ init_code_node = ast ._add_code_node ([Assignment (Variable ("a" ), Constant (0 ))])
2112
+
2113
+ while_loop = ast .factory .create_while_loop_node (logic_cond ("x1" , context ))
2114
+ while_loop_body = ast .factory .create_seq_node ()
2115
+ while_loop_iteration = ast ._add_code_node ([Assignment (Variable ("a" ), BinaryOperation (OperationType .plus , [Variable ("a" ), Constant (1 )]))])
2116
+ ast ._add_node (while_loop )
2117
+ ast ._add_node (while_loop_body )
2118
+
2119
+ ast ._add_edges_from (
2120
+ [
2121
+ (root , init_code_node ),
2122
+ (root , while_loop ),
2123
+ (while_loop , while_loop_body ),
2124
+ (while_loop_body , if_condition ),
2125
+ (while_loop_body , while_loop_iteration )
2126
+ ]
2127
+ )
2128
+
2129
+ WhileLoopReplacer (ast , _generate_options ()).run ()
2130
+ assert not any (isinstance (loop_node , ForLoopNode ) for loop_node in list (ast .get_loop_nodes_post_order ()))
2131
+
2132
+ def test_skip_for_loop_recovery_if_continue_in_nested_while (self ):
2133
+ """
2134
+ while(a < 5) {
2135
+ a = a + b
2136
+ while(b < 10) {
2137
+ if(b < 0) {
2138
+ b = b + 2
2139
+ continue
2140
+ }
2141
+ b = b + 1
2142
+ }
2143
+ a = a + 1
2144
+ }
2145
+ """
2146
+ true_value = LogicCondition .initialize_true (context := LogicCondition .generate_new_context ())
2147
+ ast = AbstractSyntaxTree (
2148
+ root := SeqNode (true_value ),
2149
+ condition_map = {
2150
+ logic_cond ("x1" , context ): Condition (OperationType .less , [Variable ("a" ), Constant (5 )]),
2151
+ logic_cond ("x2" , context ): Condition (OperationType .less , [Variable ("b" ), Constant (10 )]),
2152
+ logic_cond ("x3" , context ): Condition (OperationType .less , [Variable ("b" ), Constant (0 )])
2153
+ }
2154
+ )
2155
+
2156
+ true_branch = ast ._add_code_node (
2157
+ [
2158
+ Assignment (Variable ("b" ), BinaryOperation (OperationType .plus , [Variable ("b" ), Constant (2 )])),
2159
+ Continue ()
2160
+ ]
2161
+ )
2162
+ if_condition = ast ._add_condition_node_with (logic_cond ("x3" , context ), true_branch )
2163
+
2164
+ while_loop_outer = ast .factory .create_while_loop_node (logic_cond ("x1" , context ))
2165
+ while_loop_body_outer = ast .factory .create_seq_node ()
2166
+ while_loop_iteration_outer_1 = ast ._add_code_node ([Assignment (Variable ("a" ), BinaryOperation (OperationType .plus , [Variable ("a" ), Variable ("b" )]))])
2167
+ while_loop_iteration_outer_2 = ast ._add_code_node ([Assignment (Variable ("a" ), BinaryOperation (OperationType .plus , [Variable ("a" ), Constant (1 )]))])
2168
+ ast ._add_node (while_loop_outer )
2169
+ ast ._add_node (while_loop_body_outer )
2170
+
2171
+ while_loop_inner = ast .factory .create_while_loop_node (logic_cond ("x2" , context ))
2172
+ while_loop_body_inner = ast .factory .create_seq_node ()
2173
+ while_loop_iteration_inner = ast ._add_code_node ([Assignment (Variable ("b" ), BinaryOperation (OperationType .plus , [Variable ("b" ), Constant (1 )]))])
2174
+ ast ._add_node (while_loop_inner )
2175
+ ast ._add_node (while_loop_body_inner )
2176
+
2177
+ ast ._add_edges_from (
2178
+ [
2179
+ (root , while_loop_outer ),
2180
+ (while_loop_outer , while_loop_body_outer ),
2181
+ (while_loop_body_outer , while_loop_inner ),
2182
+ (while_loop_body_outer , while_loop_iteration_outer_1 ),
2183
+ (while_loop_body_outer , while_loop_iteration_outer_2 ),
2184
+ (while_loop_inner , while_loop_body_inner ),
2185
+ (while_loop_body_inner , if_condition ),
2186
+ (while_loop_body_inner , while_loop_iteration_inner )
2187
+ ]
2188
+ )
2189
+
2190
+ WhileLoopReplacer (ast , _generate_options ()).run ()
2191
+ loop_nodes = list (ast .get_loop_nodes_post_order ())
2192
+ assert not isinstance (loop_nodes [0 ], ForLoopNode ) and isinstance (loop_nodes [1 ], ForLoopNode )
0 commit comments