Skip to content

Commit 0be5830

Browse files
author
Spartak Ehrlich
committed
Merge branch 'main' into issue-309-_Hungarian_Notation_Variables_with_different_names_but_same_labels_are_renamed_to_the_same_variable
2 parents 5998a70 + 8e40c13 commit 0be5830

File tree

2 files changed

+116
-0
lines changed

2 files changed

+116
-0
lines changed

decompiler/pipeline/controlflowanalysis/readability_based_refinement.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,9 @@ def run(self):
287287
or self._invalid_simple_for_loop_condition_type(loop_node.condition):
288288
continue
289289

290+
if any(node.does_end_with_continue for node in loop_node.body.get_descendant_code_nodes_interrupting_ancestor_loop()):
291+
continue
292+
290293
if not self._force_for_loops and loop_node.condition.get_complexity(self._ast.condition_map) > self._condition_max_complexity:
291294
continue
292295

tests/pipeline/controlflowanalysis/test_readability_based_refinement.py

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
from decompiler.pipeline.controlflowanalysis.readability_based_refinement import (
55
ForLoopVariableRenamer,
66
ReadabilityBasedRefinement,
7+
WhileLoopReplacer,
78
WhileLoopVariableRenamer,
89
_find_continuation_instruction,
910
_has_deep_requirement,
@@ -19,6 +20,7 @@
1920
Call,
2021
Condition,
2122
Constant,
23+
Continue,
2224
ImportedFunctionSymbol,
2325
ListOperation,
2426
OperationType,
@@ -2077,3 +2079,114 @@ def test_declaration_listop(self, ast_call_for_loop):
20772079
for node in ast_call_for_loop:
20782080
if isinstance(node, ForLoopNode):
20792081
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

Comments
 (0)