Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Breaks/Continues/Early Returns GCC -> CAST Pull Request #265

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 46 additions & 1 deletion automates/program_analysis/GCC2GrFN/gcc_ast_to_cast.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
UnaryOperator,
VarType,
Var,
loop,
source_ref,
subscript,
)
Expand Down Expand Up @@ -64,6 +65,7 @@ def __init__(self, gcc_asts):
self.parsed_basic_blocks = []
self.current_basic_block = None
self.type_ids_to_defined_types = {}
self.loop_exits = {}

def to_cast(self):
modules = []
Expand Down Expand Up @@ -489,6 +491,10 @@ def parse_conditional_statement(self, stmt, statements):
condition_expr = self.parse_conditional_expr(stmt)

if is_loop:

src_index = self.current_basic_block["index"]
self.loop_exits[src_index] = (src_index,stmt["trueLabel"])

temp = self.current_basic_block
loop_body = self.parse_body(false_edge, true_edge)
self.current_basic_block = temp
Expand All @@ -514,12 +520,49 @@ def parse_conditional_statement(self, stmt, statements):
# this second condition. Otherwise, we only have one condition and
# the "false block" is the normal block of code following the if,
# so do not evaluate it here.
# In the case that a block has a break in it, the first check won't work
# because the break changes the exit target of the block it's in, so we do
# additional checks to see where the break takes us
if true_exit_target == false_exit_target:
false_res = self.parse_basic_block(false_block)
elif true_exit_target != false_exit_target and true_exit_target > true_block["edges"][0]["source"]:
titomeister marked this conversation as resolved.
Show resolved Hide resolved
false_res = self.parse_basic_block(false_block)


self.current_basic_block = temp
return [ModelIf(expr=condition_expr, body=true_res, orelse=false_res)]

def parse_predict_stmt(self, stmt):
if stmt["name"] == "continue":
return [ModelContinue()]
if "early return" in stmt["name"]:
curr_b = self.current_basic_block
ret_val = curr_b["statements"][0]["operands"][0]
titomeister marked this conversation as resolved.
Show resolved Hide resolved
val = self.parse_operand(ret_val)
return [ModelReturn(value=val)]
else:
return []

def parse_goto_stmt(self, stmt):

# Attempt to find which block this goto statement is from
if len(self.loop_exits) > 0:
loop_indices = list(self.loop_exits.keys())
curr = self.loop_exits[loop_indices[0]]
target = stmt["target"]

for loop_index in self.loop_exits:
titomeister marked this conversation as resolved.
Show resolved Hide resolved
loop_block = self.loop_exits[loop_index]
if target >= loop_block[0] and target <= loop_block[1]:
if loop_block[0] > curr[0] and loop_block[0] < curr[1]:
titomeister marked this conversation as resolved.
Show resolved Hide resolved
curr = loop_block

if target == curr[1]:
return [ModelBreak()]

return []


def parse_body(self, start_block, end_block):
blocks = [
bb
Expand All @@ -541,12 +584,14 @@ def parse_statement(self, stmt, statements):
result = self.parse_call_statement(stmt)
elif stmt_type == "conditional":
result = self.parse_conditional_statement(stmt, statements)
elif stmt_type == "predict":
result = self.parse_predict_stmt(stmt)
elif (
# Already handled in the conditional stmt type, just skip
stmt_type == "goto"
or stmt_type == "resx" # Doesnt concern us
):
return []
result = self.parse_goto_stmt(stmt)
else:
# TODO custom exception
raise Exception(f"Error: Unknown statement type {stmt_type}")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
int main()
{
int x = 10;
int y = 0;
while (y < x)
{
y = y + 1;

if (y == 5)
{
x = x - 1;
break;
}
else
y = 5;

y = y - x;
}

return 1;
}
Loading