示例#1
0
ArrayVariable*
ArrayVariable::rnd_mutate(void)
{
	assert(0 && "invalid call to rnd_mutate");
	bool use_existing = rnd_flipcoin(20);
	ERROR_GUARD(NULL);
	size_t i;
	if (use_existing) {
		vector<Variable*> ok_vars;
		for (i=0; i<parent->local_vars.size(); i++) {
			if (is_variant(parent->local_vars[i])) {
				ok_vars.push_back(parent->local_vars[i]);
			}
		}
		Variable* v = VariableSelector::choose_ok_var(ok_vars);
		ERROR_GUARD(NULL);
		if (v) {
			ArrayVariable* av = dynamic_cast<ArrayVariable*>(v);
			return av;
		}
	}
	vector<const Expression*> new_indices;
	vector<bool> mutate_flags;
	bool no_mutate = true;
	for (i=0; i<get_dimension(); i++) {
		bool mutate = rnd_flipcoin(10);
		ERROR_GUARD(0);
		mutate_flags.push_back(mutate);
		if (mutate) {
			no_mutate = false;
		}
	}
	// if no mutation, return self
	if (no_mutate) {
		return this;
	}
	for (i=0; i<get_dimension(); i++) {
		if (mutate_flags[i]) {
			const Expression* e = indices[i];
			assert(e->term_type == eVariable);
			const ExpressionVariable* ev = dynamic_cast<const ExpressionVariable*>(e);
			// create a mutated index from the original by adding an constant offset
			FunctionInvocation* fi = new FunctionInvocationBinary(eAdd, 0);
        	fi->add_operand(new ExpressionVariable(*(ev->get_var())));
			int offset = rnd_upto(sizes[i]);
			if (offset == 0) offset = 1;	// give offset 1 more chance
			ERROR_GUARD(NULL);
			ostringstream oss;
			oss << offset;
        	fi->add_operand(new Constant(get_int_type(), oss.str()));
        	Expression* mutated_e = new ExpressionFuncall(*fi);
			new_indices.push_back(mutated_e);
		}
		else {
			new_indices.push_back(indices[i]->clone());
		}
	}
	// if index of at least one dimension mutated, return the new variable
	return VariableSelector::create_mutated_array_var(this, new_indices);
}
示例#2
0
StatementAssign *
StatementAssign::make_possible_compound_assign(CGContext &cg_context, 
				 const Lhs &l,
				 eAssignOps op,
				 const Expression &e)
{
	eBinaryOps bop = compound_to_binary_ops(op);
	const Expression *rhs = NULL;
	SafeOpFlags *fs = NULL;
	std::string tmp1;
	std::string tmp2;

	if (bop != MAX_BINARY_OP) {
		//SafeOpFlags *local_fs = SafeOpFlags::make_random(sOpAssign, true);
		SafeOpFlags *local_fs  = NULL;
		FunctionInvocation* fi = NULL;
		if (safe_assign(op)) {
			local_fs = SafeOpFlags::make_dummy_flags();
			fi = new FunctionInvocationBinary(bop, local_fs);
		}
		else {
			local_fs = SafeOpFlags::make_random(sOpAssign);
			
			fi = FunctionInvocationBinary::CreateFunctionInvocationBinary(cg_context, bop, local_fs);
			tmp1 = dynamic_cast<FunctionInvocationBinary*>(fi)->get_tmp_var1();
			tmp2 = dynamic_cast<FunctionInvocationBinary*>(fi)->get_tmp_var2();			
		}
		fs = local_fs->clone();
        	fi->add_operand(new ExpressionVariable(*(l.get_var()), &l.get_type()));
        	fi->add_operand(e.clone());
        	rhs = new ExpressionFuncall(*fi);
        }
	else {
		rhs = &e;
#if 0
		if (e.term_type == eFunction) {
			const ExpressionFuncall* func = dynamic_cast<const ExpressionFuncall*>(&e);
			if (!func->get_invoke().safe_invocation()) {
				fs = SafeOpFlags::make_dummy_flags();
				fs = NULL;
			}
		}
#endif
		if (op != eSimpleAssign) {
			fs = SafeOpFlags::make_random(sOpAssign);
			bool op1 = fs->get_op1_sign();
			bool op2 = fs->get_op2_sign();
			enum SafeOpSize size = fs->get_op_size();

			eSimpleType type1 = SafeOpFlags::flags_to_type(op1, size);
			eSimpleType type2 = SafeOpFlags::flags_to_type(op2, size);

			const Block *blk = cg_context.get_current_block();
			assert(blk);

			tmp1 = blk->create_new_tmp_var(type1);
			tmp2 = blk->create_new_tmp_var(type2);
			
		}
	}
	StatementAssign *sa = new StatementAssign(cg_context.get_current_block(), l, op, e, rhs, fs, tmp1, tmp2);
	return sa;
}