def insertTest(self,block,functionName,varVals,varTypes,timer,preOut,testId): #Fork call cFork=c_ast.Assignment( lvalue=c_ast.ID(name='child_pid'), op='=', rvalue=c_ast.FuncCall( c_ast.ID(name='fork'), args=None)) #Child ##stdout = freopen("out.txt", "w", stdout); if self.functype=='int': printLeft=c_ast.Constant(type="char",value='"'+"%d" +'"') elif self.functype=='float' or self.functype=='double': printLeft=c_ast.Constant(type="char",value='"'+"%f" +'"') else: printLeft=c_ast.Constant(type="char",value='"'+"%d" +'"') fileOut=c_ast.Constant(type="char",value='"'+preOut +'.' +testId+".out.txt" +'"') fileW=c_ast.Constant(type="char",value='"'+"w" +'"') fileStdout=c_ast.ID(name='stdout') expressList = [fileOut,fileW,fileStdout] freopenC = c_ast.FuncCall(c_ast.ID(name="freopen"),c_ast.ExprList(expressList)) outReassign=c_ast.Assignment( lvalue=fileStdout, op='=', rvalue=freopenC) ##mainfake() expressList = list(c_ast.Constant(type=varTypes[i],value=str(varVals[i])) for i in range(len(varVals))) funcCall = c_ast.FuncCall(c_ast.ID(name=functionName),c_ast.ExprList(expressList)) expressList = [printLeft,funcCall] funcCall = c_ast.FuncCall(c_ast.ID(name="printf"),c_ast.ExprList(expressList)) ##exit(0) funcCall2 = c_ast.FuncCall(c_ast.ID(name="exit"),c_ast.ExprList([c_ast.Constant(type='int',value='0')])) #Parent cAlarm=c_ast.FuncCall( c_ast.ID(name='alarm'),c_ast.ExprList([c_ast.Constant(type='int',value=str(timer))])) cWait=c_ast.FuncCall( c_ast.ID(name='wait'),c_ast.ExprList([c_ast.ID(name='0')])) #IFs if_false= c_ast.If( c_ast.BinaryOp(left=c_ast.ID(name='child_pid'),op='==',right= c_ast.Constant(type='int',value='0')), c_ast.Compound([outReassign,funcCall,funcCall2]),iffalse=None) if_ini=c_ast.If( c_ast.BinaryOp(left=c_ast.ID(name='child_pid'),op='>',right= c_ast.Constant(type='int',value='0')), c_ast.Compound([cAlarm,cWait]),iffalse=if_false) block.body.block_items.insert(1,if_ini) block.body.block_items.insert(1,cFork)
def create_capture_node(new_vars, var, index, while_body): """Create an assignment capture node (new_vars = var)""" tab = [] if isinstance(while_body[index], (c_ast.While, c_ast.If)): tab.append(c_ast.Assignment("=", c_ast.ID(new_vars[1]), while_body[index].cond)) tab.append(c_ast.Assignment("=", c_ast.ID(new_vars[0]), c_ast.ID(var))) return tab
def create_capture_node(new_vars, var, i, while_node): tab = [] tab.append(c_ast.Assignment("=", c_ast.ID(new_vars[0]), c_ast.ID(var))) if iscond(while_node.stmt.block_items[i]): tab.append( c_ast.Assignment("=", c_ast.ID(new_vars[1]), while_node.stmt.block_items[i].cond)) tab.reverse() return tab
def generic_visit(self, node): if (node.coord): # Extract and check line number lineNum = str(node.coord)[str(node.coord).index(':')+1:] if (lineNum == self.faultyLine): if isinstance(node, c_ast.Assignment): # Replace with symbolic assignment return node elif isinstance(node, c_ast.If): # Add variable, make it symbolic return node elif isinstance(node, c_ast.Return): # Add variable, make it symbolic return node elif isinstance(node, c_ast.Decl): return node for c_name, c in node.children(): # recursively visit child nodes res = self.visit(c) if (res): if isinstance(node, c_ast.FuncDef) or isinstance(node, c_ast.Compound) or isinstance(node, c_ast.FileAST): if isinstance(node, c_ast.FuncDef): items = node.body.block_items elif isinstance(node, c_ast.Compound): items = node.block_items else: items = node.ext for i, n in enumerate(items): if res == n: if isinstance(res, c_ast.Assignment): newNode = c_ast.FuncCall(c_ast.ID('klee_make_symbolic'), c_ast.ExprList([c_ast.ID('&'+res.lvalue.name), c_ast.FuncCall(c_ast.ID('sizeof'), c_ast.ExprList([res.lvalue])), c_ast.Constant('str', '"'+res.lvalue.name+'"')])) items.insert(i+1, newNode) return elif isinstance(res, c_ast.If): newAssign = c_ast.Assignment('=', c_ast.ID('kleeVar'), res.cond) newNode = c_ast.FuncCall(c_ast.ID('klee_make_symbolic'), c_ast.ExprList([c_ast.ID('&kleeVar'), c_ast.FuncCall(c_ast.ID('sizeof'), c_ast.ExprList([c_ast.ID('kleeVar')])), c_ast.Constant('str', '"kleeVar"')])) n.cond = c_ast.ID('kleeVar') items.insert(i, newAssign) items.insert(i+1, newNode) return elif isinstance(res, c_ast.Return): newAssign = c_ast.Assignment('=', c_ast.ID('kleeVar'), res.expr) newNode = c_ast.FuncCall(c_ast.ID('klee_make_symbolic'), c_ast.ExprList([c_ast.ID('&kleeVar'), c_ast.FuncCall(c_ast.ID('sizeof'), c_ast.ExprList([c_ast.ID('kleeVar')])), c_ast.Constant('str', '"kleeVar"')])) n.expr = c_ast.ID('kleeVar') items.insert(i, newAssign) items.insert(i+1, newNode) return elif isinstance(res, c_ast.Decl): newNode = c_ast.FuncCall(c_ast.ID('klee_make_symbolic'), c_ast.ExprList([c_ast.ID('&'+res.name), c_ast.FuncCall(c_ast.ID('sizeof'), c_ast.ExprList([c_ast.ID(res.name)])), c_ast.Constant('str', '"'+res.name+'"')])) items.insert(i+1, newNode) return else: return res
def _instrument(self, types1, types2, pc): if not isinstance(types1, TypeSystem) or not isinstance(types2, TypeSystem): raise ValueError('types1 and types2 must be TypeSystem') query_var_checker = _ExpressionFinder( lambda node: isinstance(node, c_ast.ArrayRef) and '__SHADOWDP_' in node.name.name and self._parameters[2] in node.name.name) assumes, inserted_statement = [], [] for name, distances1 in types1.variables(): if name not in types2: continue distances2 = types2.get_distance(name) for type_index in range(2): version = 'ALIGNED' if type_index == 0 else 'SHADOW' if distances1[type_index] != '*' and distances2[type_index] == '*': for query in query_var_checker.visit(convert_to_ast(distances1[type_index])): assumes.extend(self._assume_query(query)) self._inserted_query_assumes[-1].append(query) if type_index == 0 or (type_index == 1 and not pc): inserted_statement.append(c_ast.Assignment( op='=', lvalue=c_ast.ID('__SHADOWDP_{}_DISTANCE_{}'.format(version, name)), rvalue=convert_to_ast(distances1[type_index]))) return assumes + inserted_statement
def __for_loop(self, depth: int) -> c_ast.For: """ A helper function to construct a for loop corresponding to allocating one dimension of an array. Recursively calls itself to generate next levels or generates an initialisation line if it is the last level. Example: for(i_2 = 0; i_2 < N; i_2++) { ... } :param depth: :return: C-ast.For """ i = self.counter_prefix + str(depth) init = c_ast.DeclList([ c_ast.Decl(c_ast.ID(i), [], [], [], c_ast.TypeDecl(i, [], c_ast.IdentifierType(['int'])), c_ast.Constant('int', '0'), '') ]) cond = c_ast.BinaryOp('<', c_ast.ID(i), self.sizes[depth]) nxt = c_ast.Assignment('++', c_ast.ID(i), None) stmt = c_ast.Compound([]) if depth < len(self.sizes) - 1: stmt.block_items = [ self.__malloc_assign(depth + 1), self.__for_loop(depth + 1) ] else: stmt.block_items = [self.initialiser(depth + 1)] return c_ast.For(init, cond, nxt, stmt)
def on_preincrement_node(self, expr_node): # this is kinda hacky but w/e return self.on_assign_node( c_ast.Assignment('+=', expr_node, c_ast.Constant('int', '1'), coord=expr_node.coord))
def nested_for_loop(node, inner_loop_body, loop_iterator_base, rename_index=0): """ Recursively create nested for loops for copying a multi-dimensional array. """ if isinstance(node.type.type, c_ast.ArrayDecl): # Multi-dimensional array, recurse to generate inner loop for_loop_body = nested_for_loop(node.type, inner_loop_body, loop_iterator_base, rename_index + 1) else: # Single or last dimension of array for_loop_body = [inner_loop_body] # Declare iterator loop_iterator = c_ast.ID("%s_i%d" % (loop_iterator_base, rename_index)) loop_iterator_decl = c_ast.Decl( loop_iterator.name, [], [], [], c_ast.TypeDecl(loop_iterator.name, [], c_ast.IdentifierType(["int"])), None, None) # For loop array_size = node.type.dim for_loop = c_ast.For( c_ast.Assignment('=', loop_iterator, c_ast.Constant("int", "0")), c_ast.BinaryOp('<', loop_iterator, array_size), c_ast.UnaryOp('p++', loop_iterator), c_ast.Compound(for_loop_body)) return [loop_iterator_decl, for_loop]
def pre_argument(self, name): commands = [] commands.append( _generate_decl( name + '_int', c_ast.TypeDecl(name + '_int', [], c_ast.IdentifierType(['unsigned', 'int'])))) commands.append(_generate_read(name + '_int')) commands.append( c_ast.Assignment('|=', c_ast.ID(name + '_int'), c_ast.Constant('int', PTR_OFFSET))) commands.append( c_ast.Decl( name, [], [], [], c_ast.PtrDecl( [], c_ast.TypeDecl(name, [], c_ast.IdentifierType(['void'])), ), c_ast.Cast( c_ast.Typename( None, [], c_ast.PtrDecl([], c_ast.TypeDecl( None, [], c_ast.IdentifierType(['void'])))), c_ast.ID(name + '_int')), [])) return commands
def v_Decl(self, n): #if visited in stack then its safe to say that we have a local var var_name = n.name if len(n.storage) != 0: var_storage = n.storage[0] else: var_storage = None if var_storage == None: self.symbol_table.append([ var_name, #store a var to the stack with the offset of whatever number of vars we alredy loaded self.int_var, "local", "stack" ]) self.int_var += 1 elif var_storage.lower() == "register": self.symbol_table.append( [var_name, self.register_pointer, "local", "register"]) self.register_pointer += 1 if n.init != None: #a intiliser is = to imediatly assign so just do a assignment assi = c_ast.Assignment('=', c_ast.ID(var_name), n.init) self.t_stat_stack.append("Assignment") self.v_Assignemnt(assi) self.t_stat_stack.pop()
def insertTest(self,block,functionName,varVals,varTypes,timer): #Fork call cFork=c_ast.Assignment( lvalue=c_ast.ID(name='child_pid'), op='=', rvalue=c_ast.FuncCall( c_ast.ID(name='fork'), args=None)) #Child if self.functype=='int' or self.functype=="bool": printLeft=c_ast.Constant(type="char",value='"'+"%d" +'"') elif self.functype=='float' or self.functype=='double': printLeft=c_ast.Constant(type="char",value='"'+"%f" +'"') else: printLeft=c_ast.Constant(type="char",value='"'+"%d" +'"') expressList = list(c_ast.Constant(type=varTypes[i],value=str(varVals[i])) for i in range(len(varVals))) funcCall = c_ast.FuncCall(c_ast.ID(name=functionName),c_ast.ExprList(expressList)) expressList = [printLeft,funcCall] funcCall = c_ast.FuncCall(c_ast.ID(name="printf"),c_ast.ExprList(expressList)) funcCall2 = c_ast.FuncCall(c_ast.ID(name="exit"),c_ast.ExprList([c_ast.Constant(type='int',value='0')])) #Parent cAlarm=c_ast.FuncCall( c_ast.ID(name='alarm'),c_ast.ExprList([c_ast.Constant(type='int',value=str(timer))])) cWait=c_ast.FuncCall( c_ast.ID(name='wait'),c_ast.ExprList([c_ast.ID(name='0')])) #IFs if_false= c_ast.If( c_ast.BinaryOp(left=c_ast.ID(name='child_pid'),op='==',right= c_ast.Constant(type='int',value='0')), c_ast.Compound([funcCall,funcCall2]),iffalse=None) if_ini=c_ast.If( c_ast.BinaryOp(left=c_ast.ID(name='child_pid'),op='>',right= c_ast.Constant(type='int',value='0')), c_ast.Compound([cAlarm,cWait]),iffalse=if_false) block.body.block_items.insert(1,if_ini) block.body.block_items.insert(1,cFork)
def _assign(self, variable: Union[c_ast.ID, c_ast.ArrayRef], expression: ExprType, node: c_ast.Node): """T-Asgn rule, which can be re-used both in Assignment node and Decl node""" # get new distance from the assignment expression (T-Asgn) variable_name = variable.name if isinstance( variable, c_ast.ID) else variable.name.name var_aligned, var_shadow, *_ = self._type_system.get_types( variable_name) aligned, shadow = DistanceGenerator( self._type_system).visit(expression) if self._loop_level == 0: # insert x^align = n^align if x^aligned is * if var_aligned == '*' or aligned != '0': self._insert_at( node, parse( f'{constants.ALIGNED_DISTANCE}_{variable_name} = {aligned}' ), after=True) if self._enable_shadow: # generate x^shadow = x + x^shadow - e according to (T-Asgn) if self._pc: if isinstance(variable, c_ast.ID): shadow_distance = c_ast.ID( name=f'{constants.SHADOW_DISTANCE}_{variable_name}' ) elif isinstance(variable, c_ast.ArrayRef): shadow_distance = c_ast.ArrayRef( name=f'{constants.SHADOW_DISTANCE}_{variable_name}', subscript=variable.subscript) else: raise NotImplementedError( f'Assigned value type not supported {type(variable)}' ) # insert x^shadow = x + x^shadow - e; insert_node = c_ast.Assignment( op='=', lvalue=shadow_distance, rvalue=c_ast.BinaryOp(op='-', left=c_ast.BinaryOp( op='+', left=variable, right=shadow_distance), right=expression)) self._insert_at(node, insert_node, after=False) # insert x^shadow = n^shadow if n^shadow is not 0 elif var_shadow == '*' or shadow != '0': self._insert_at( node, parse( f'{constants.SHADOW_DISTANCE}_{variable_name} = {shadow}' ), after=True) shadow_distance = '*' if self._pc or shadow != '0' or var_shadow == '*' else '0' aligned_distance = '*' if aligned != '0' or var_aligned == '*' else '0' self._type_system.update_distance(variable_name, aligned_distance, shadow_distance)
def astAssiDef(isr): larr = c_ast.ArrayRef( c_ast.ID('deferral'), c_ast.Constant( 'int', str(int(isr) - 1))) # the second param of Constant is String rarr = c_ast.UnaryOp('&', c_ast.ID('deferral_' + isr)) assi = c_ast.Assignment('=', larr, rarr) return assi
def visit_FuncDef(self, node): label = c_ast.Label("predict_exec_time", c_ast.EmptyStatement()) decl = c_ast.Decl("exec_time", None, None, None, c_ast.TypeDecl("exec_time", None, c_ast.IdentifierType(["float"])), None, None) assignment = c_ast.Assignment('=', c_ast.ID("exec_time"), c_ast.Constant("int", 0)) ret = c_ast.Return(c_ast.ID("exec_time")) compound = c_ast.Compound([label, decl, assignment, ret]) node.body.block_items.append(compound)
def rename_bounds(self): """ Inserts a code fragment initializing program parameters. The actual values should be injected at compilation time (-D option in gcc) """ inits = [ c_ast.Assignment('=', c_ast.ID(n), c_ast.ID('PARAM_' + n.upper())) for n in self.bounds ] self.main.body.block_items[0:0] = inits
def visit_FuncDef(self, node): # Skip if no loop counters exist if self.loop_counter_size == 0: return # Create loop_counter declaration/initialization constants = [c_ast.Constant("int", '0') for i in range(self.loop_counter_size)] init_list = c_ast.InitList(constants) identifier_type = c_ast.IdentifierType(["int"]) type_decl = c_ast.TypeDecl("loop_counter", [], identifier_type) dim = c_ast.Constant("int", str(self.loop_counter_size)) array_decl = c_ast.ArrayDecl(type_decl, dim, []) decl = c_ast.Decl("loop_counter", [], [], [], array_decl, init_list, None) node.body.block_items.insert(0, decl) # Label for return values to goto start_label = c_ast.Label("print_loop_counter", c_ast.EmptyStatement()) # Start and end labels used for inserting preprocessor commands for #if DEBUG_EN end_label = c_ast.Label("print_loop_counter_end", c_ast.EmptyStatement()) # Write to file if self.write_to_file: stmt = c_ast.ID("write_array(loop_counter, %d)\n" % (self.loop_counter_size)) compound = c_ast.Compound([start_label, stmt, end_label]) # Print to stdout else: # Add printf to the end of function # Start of printing stmt_start = c_ast.ID("printf(\"loop counter = (\")") # For loop # int i; identifier_type = c_ast.IdentifierType(["int"]) type_decl = c_ast.TypeDecl("i", [], identifier_type) for_decl = c_ast.Decl("i", [], [], [], type_decl, [], None) # i = 0 init = c_ast.Assignment("=", c_ast.ID("i"), c_ast.Constant("int", '0')) # i < self.loop_counter_size cond = c_ast.BinaryOp("<", c_ast.ID("i"), c_ast.Constant("int", str(self.loop_counter_size))) # i++ next_stmt = c_ast.UnaryOp("p++", c_ast.ID("i")) # printf in for stmt = c_ast.ID("printf(\"%d, \", loop_counter[i])") # Cosntruct for loop stmt_for = c_ast.For(init, cond, next_stmt, stmt) # End of printing stmt_end = c_ast.ID("printf(\")\\n\")") # Put it all together body = c_ast.Compound([stmt_start, for_decl, stmt_for, stmt_end]) # Surround with labels compound = c_ast.Compound([start_label, body, end_label]) node.body.block_items.append(compound)
def visit_Return(self, node): if node.expr is not None: decl = c_ast.Assignment('=', c_ast.ID('return_of_the_jedi'), node.expr) self.insert_node_before(decl) node.expr = None if hasattr(self._currentFunc.decl, 'poroto_type'): return_type = self._currentFunc.decl.poroto_type.dereference() reference_type = c_ast.PtrDecl([], return_type.user_type_tree) reference_type.type.poroto_type = return_type poroto_type = types.PointerDescriptor(reference_type, None, None) decl.lvalue.poroto_type = poroto_type
def papi_instr() -> Tuple[List[c_ast.Node], List[c_ast.Node]]: """ :return: c_ast nodes representing the following code: exec(PAPI_start(set)); *begin = clock(); ... *end = clock(); exec(PAPI_stop(set, values)); """ papi_start = c_ast.FuncCall(c_ast.ID('PAPI_start'), c_ast.ParamList([c_ast.ID('set')])) papi_stop = c_ast.FuncCall(c_ast.ID('PAPI_stop'), c_ast.ParamList([c_ast.ID('set'), c_ast.ID('values')])) exec_start = c_ast.FuncCall(c_ast.ID('exec'), c_ast.ParamList([papi_start])) exec_stop = c_ast.FuncCall(c_ast.ID('exec'), c_ast.ParamList([papi_stop])) clock = c_ast.FuncCall(c_ast.ID('clock'), c_ast.ParamList([])) begin_clock = c_ast.Assignment('=', c_ast.UnaryOp('*', c_ast.ID('begin')), clock) end_clock = c_ast.Assignment('=', c_ast.UnaryOp('*', c_ast.ID('end')), clock) return [exec_start, begin_clock], [end_clock, exec_stop]
def assign_results(outargs, code): ptroutargs = [deepcopy(arg) for arg in outargs] rename = RenameVisitor("out") for arg in ptroutargs: rename.visit(arg) arg.type = c_ast.PtrDecl([], arg.type) arg.init = None for ptr, var in zip(ptroutargs, outargs): code.append( c_ast.Assignment('=', c_ast.UnaryOp('*', c_ast.ID(ptr.name)), c_ast.ID(var.name)))
def __malloc_assign(self, depth: int) -> c_ast.Node: """ A helper function to construct a malloc function call with assigment Example: A[i_0] = malloc((N + 2) * sizeof(int*)); :param depth: :return: """ subs = self.__subs(depth) return c_ast.Assignment('=', self.__array_ref(subs), self.__malloc(depth))
def ConvertPreIncDecToCompoundAssignment(ast, meta_info): def IsPreIncDec(node, _parent): return isinstance(node, c_ast.UnaryOp) and node.op in common.PRE_INC_DEC_OPS candidates = common.FindMatchingNodesPostOrder(ast, ast, IsPreIncDec) meta_info.type_links[CONST_ONE] = meta.INT_IDENTIFIER_TYPE for node, parent in candidates: op = "+=" if node.op == "++" else "-=" a = c_ast.Assignment(op, node.expr, CONST_ONE) meta_info.type_links[a] = meta_info.type_links[node.expr] common.ReplaceNode(parent, node, a)
def astScheReg(reg): #the type of reg is String exlist = [c_ast.ID(reg)] exprs = c_ast.ExprList(exlist) rfunc = c_ast.FuncCall(c_ast.ID('scheduler_reg'), exprs) schereg = c_ast.Assignment('=', c_ast.ID(reg), rfunc) # schereg=astseq.ext[166].body.block_items[3] # print ("\033[1;5;32;45;1mFuncCall scheduler_deferral\033[0m") # schereg.lvalue.name=reg #the type of lvalue is c_ast.ID # schereg.rvalue.args.exprs[0].name=reg #the type of exprs is c_ast.ExprList and the type of exprs[0] is c_ast.ID # print ("\033[1;5;32;45;1m schereg.rvalue.args.exprs[0]\033[0m") # print(schereg.rvalue.args); # schereg.rvalue.args.show() # print ("\033[1;5;32;45;1mFuncCall scheduler_reg\033[0m") # schereg.show() return schereg
def generic_visit(self, node): for ci, (c_name, c) in enumerate(node.children()): # Return statement if isinstance(c, c_ast.Return): # Create a new compound node insert_node = c_ast.Compound([]) # If there is a return value, add statement for return_value = value if c.expr: insert_node.block_items.append(c_ast.Assignment("=", c_ast.ID("return_value"), c.expr)) # Add goto to end of function block insert_node.block_items.append(c_ast.Goto(self.goto_name)) # Replace original node with new node replace_node(node, insert_node, ci, c_name) # Non-return statement, continue visiting else: self.visit(c)
def addGlobalParams(self): glob_vis = GlobalVisitor.GlobalVisitor() for var in glob_vis.getVariables(self.ast): varAlt = deepcopy(var) varAlt.name = '__global__' + varAlt.name if (not (isinstance(varAlt.type, c_ast.ArrayDecl)) and not (isinstance(varAlt.type, c_ast.FuncDecl))): #print(varAlt.type) varAlt.type.declname = varAlt.name assignmentVars = c_ast.Assignment(op='=', lvalue=c_ast.ID(var.name), rvalue=c_ast.ID(varAlt.name)) if (varAlt.init != None): varAlt.init = None self.params.params.append(varAlt) self.target.body.block_items.insert(0, assignmentVars)
def visit_FuncCall(self, node): if isinstance(node, c_ast.FuncCall): if (node.name.name == (self.lib_name + "_old") or node.name.name == (self.lib_name + "_new")): post_fix = node.name.name[4:] parent = self.parent_child.get(node, None) if parent is not None and isinstance(parent, c_ast.Assignment): if node.name.name == (self.lib_name + "_old"): self.old_hit = True elif node.name.name == (self.lib_name + "_new"): self.new_hit = True grandparent = self.parent_child.get(parent, None) if grandparent is not None and isinstance( grandparent, c_ast.Compound): if node.args is not None: for i in range(len(node.args.exprs)): input_variable_name = "input_{d}_".format( d=self.arg_list[i].name) + post_fix input_variable = c_ast.ID( name="input_{d}_".format( d=self.arg_list[i].name) + post_fix) self.tobeInsertedBefore.append( (grandparent, parent, c_ast.Decl( name=input_variable_name, quals=[], storage=[], init=None, funcspec=[], bitsize=None, type=c_ast.TypeDecl( declname=input_variable_name, quals=[], type=c_ast.IdentifierType(['int' ]))))) self.tobeInsertedBefore.append( (grandparent, parent, make_klee_symbolic( input_variable_name, input_variable_name))) self.tobeInsertedBefore.append( (grandparent, parent, c_ast.Assignment( op='=', lvalue=input_variable, rvalue=node.args.exprs[i]))) self.invoc.append((grandparent, parent))
def expand_visit(self, node): """ Replace node with full function. """ # For each child for ci, (c_name, c) in enumerate(node.children()): ########################################## # Assignment with function call as rvalue ########################################## if isinstance(c, c_ast.Assignment) and isinstance(c.rvalue, c_ast.FuncCall): # Find matching function body for function in self.functions: name = get_function_name(c.rvalue) if name == function.decl.name: # Create the inline version of the function body inline_function = self.create_inline_function(function, c.rvalue) # Set assignment lvalue to return value inline_function.body.block_items.append(c_ast.Assignment("=", c.lvalue, c_ast.ID("return_value"))) # Replace node in parent replace_node(node, inline_function.body, ci, c_name) self.expanded = True ################################# # Function call ################################# elif isinstance(c, c_ast.FuncCall): # Look for function in function list for function in self.functions: # FIXME: Skip pointer referenced function call (i.e., jump table) if isinstance(c.name, c_ast.UnaryOp): break if c.name.name == function.decl.name: # Create in-lined version of function function_copy = self.create_inline_function(function, c) # Replace with full function replace_node(node, function_copy.body, ci, c_name) self.expanded = True ################################# # Other - Continue visiting ################################# else: self.expand_visit(c)
def replaceByPrint(self, ast): expressList = [ c_ast.Constant(type='string', value='"[[REACHED]]"') ] ifexpress = c_ast.Assignment(op="=", lvalue=c_ast.ID(name="inst_flag"), rvalue=c_ast.Constant(type='int', value='1')) self.funcCall.name = c_ast.ID(name="perror") self.funcCall.args = c_ast.ExprList(expressList) if_all = c_ast.If(c_ast.BinaryOp(left=c_ast.ID(name='inst_flag'), op='==', right=c_ast.Constant(type='int', value='0')), c_ast.Compound([self.funcCall, ifexpress]), iffalse=None) for position, inst_block in enumerate(self.inst_block): inst_block[self.inst_pos[position]] = if_all
def visit_Assignment(self, node): logger.debug('Line {}: {}'.format(str(node.coord.line), _code_generator.visit(node))) varname = node.lvalue.name if isinstance(node.lvalue, c_ast.ID) else node.lvalue.name.name if self._loop_level == 0 and self._pc: # generate x^shadow = x + x^shadow - e according to (T-Asgn) parent = self._parents[node] if isinstance(parent, c_ast.Compound): node_index = parent.block_items.index(node) if isinstance(node.lvalue, c_ast.ID): shadow_distance = c_ast.ID(name='__SHADOWDP_SHADOW_DISTANCE_{}'.format(varname)) elif isinstance(node.lvalue, c_ast.ArrayRef): shadow_distance = c_ast.ArrayRef(name='__SHADOWDP_SHADOW_DISTANCE_{}'.format(varname), subscript=node.lvalue.subscript) else: raise NotImplementedError('Assigned value type not supported {}'.format(type(node.lvalue))) # insert x^shadow = x + x^shadow - e; insert_node = c_ast.Assignment(op='=', lvalue=shadow_distance, rvalue=c_ast.BinaryOp( op='-', left=c_ast.BinaryOp(op='+', left=node.lvalue, right=shadow_distance), right=node.rvalue)) parent.block_items.insert(node_index, insert_node) self._inserted.add(insert_node) self._inserted.add(node) else: raise NotImplementedError('Parent of assignment node not supported {}'.format(type(parent))) # check the distance dependence dependence_finder = _ExpressionFinder( lambda to_check: (isinstance(to_check, c_ast.ID) and to_check.name == varname) or (isinstance(to_check, c_ast.ArrayRef) and to_check.name.name == varname), lambda to_ignore: isinstance(to_ignore, c_ast.ArrayRef) and to_ignore.name.name == self._parameters[2] ) for name, distances in self._types.variables(): if name not in self._random_variables: for distance in distances: if distance != '*': if len(dependence_finder.visit(convert_to_ast(distance))) != 0: raise DistanceDependenceError(node.coord, varname, distance) # get new distance from the assignment expression (T-Asgn) aligned, shadow = _DistanceGenerator(self._types).visit(node.rvalue) if self._pc: self._types.update_distance(node.lvalue.name, aligned, '*') else: self._types.update_distance(node.lvalue.name, aligned, shadow) logger.debug('types: {}'.format(self._types))
def perm_add_self_assignment(fn: ca.FuncDef, ast: ca.FileAST, indices: Indices, region: Region, random: Random) -> bool: """Introduce a "x = x;" somewhere.""" cands = get_insertion_points(fn, region) vars: List[str] = [] class Visitor(ca.NodeVisitor): def visit_Decl(self, decl: ca.Decl) -> None: if decl.name: vars.append(decl.name) Visitor().visit(fn.body) if not vars or not cands: return False var = random.choice(vars) where = random.choice(cands) assignment = ca.Assignment("=", ca.ID(var), ca.ID(var)) ast_util.insert_statement(where[0], where[1], assignment) return True
def addTestFunction(ast, expectedOutput, testFxn, initVars, initList): varList = [] exprList = [] fxnName = '' inFxn = False listi = 0 for i in range(len(initVars)): v = initVars[i] if inFxn: exprList.append(c_ast.Constant('int', initList[listi])) listi += 1 if (')' in v): inFxn = False newVar = c_ast.FuncCall(c_ast.ID(fxnName), c_ast.ExprList(exprList)) varList.append(newVar) exprList = [] else: if ('(' in v): fxnName = v[:v.index('(')] if (v[v.index('(')+1] != ')'): inFxn = True exprList.append(c_ast.Constant('int', initList[listi])) listi += 1 else: newVar = c_ast.FuncCall(c_ast.ID(fxnName), c_ast.ExprList([])) varList.append(newVar) else: newVar = c_ast.Assignment('=', c_ast.ID(v), c_ast.Constant('int', initList[listi])) listi += 1 varList.append(newVar) fxnDecl = c_ast.FuncDecl(None, c_ast.TypeDecl('klee_test_entry', [], c_ast.IdentifierType(['void']))) fxnCall = c_ast.FuncCall(c_ast.ID(testFxn), c_ast.ExprList([])) binaryOp = c_ast.BinaryOp('==', fxnCall, c_ast.Constant('int', expectedOutput)) ifFalse = c_ast.Compound([c_ast.FuncCall(c_ast.ID('klee_silent_exit'), c_ast.ExprList([c_ast.Constant('int', '0')]))]) ifTrue = c_ast.Compound([]) blockItems = [] for v in varList: blockItems.append(v) blockItems.append(c_ast.If(binaryOp, ifTrue, ifFalse)) fxnBody = c_ast.Compound(blockItems) fxnNode = c_ast.FuncDef(fxnDecl, None, fxnBody) ast.ext.append(fxnNode)