C-sparse

 view release on metacpan or  search on metacpan

src/sparse-0.4.4/expand.c  view on Meta::CPAN

		ormask = 0;
	return (value & andmask) | ormask;
}

void cast_value(SCTX_ struct expression *expr, struct symbol *newtype,
		struct expression *old, struct symbol *oldtype)
{
	int old_size = oldtype->bit_size;
	int new_size = newtype->bit_size;
	long long value, mask, signmask;
	long long oldmask, oldsignmask, dropped;

	if (newtype->ctype.base_type == &sctxp fp_type ||
	    oldtype->ctype.base_type == &sctxp fp_type)
		goto Float;

	// For pointers and integers, we can just move the value around
	expr->type = EXPR_VALUE;
	expr->taint = old->taint;
	if (old_size == new_size) {
		expr->value = old->value;

src/sparse-0.4.4/expand.c  view on Meta::CPAN

	// Truncate it to the new size
	signmask = 1ULL << (new_size-1);
	mask = signmask | (signmask-1);
	expr->value = value & mask;

	// Stop here unless checking for truncation
	if (!sctxp Wcast_truncate || sctxp conservative)
		return;
	
	// Check if we dropped any bits..
	oldsignmask = 1ULL << (old_size-1);
	oldmask = oldsignmask | (oldsignmask-1);
	dropped = oldmask & ~mask;

	// OK if the bits were (and still are) purely sign bits
	if (value & dropped) {
		if (!(value & oldsignmask) || !(value & signmask) || (value & dropped) != dropped)
			warning(sctx_ old->pos->pos, "cast truncates bits from constant value (%llx becomes %llx)",
				value & oldmask,
				value & mask);
	}
	return;

Float:
	if (!is_float_type(sctx_ newtype)) {
		value = (long long)old->fvalue;
		expr->type = EXPR_VALUE;

src/sparse-0.4.4/sparse.c  view on Meta::CPAN


	return check_children(sctx_ ep, bb, entry, exit);
}

static void check_cast_instruction(SCTX_ struct instruction *insn)
{
	struct symbol *orig_type = insn->orig_type;
	if (orig_type) {
		int old = orig_type->bit_size;
		int new = insn->size;
		int oldsigned = (orig_type->ctype.modifiers & MOD_SIGNED) != 0;
		int newsigned = insn->opcode == OP_SCAST;

		if (new > old) {
			if (oldsigned == newsigned)
				return;
			if (newsigned)
				return;
			warning(sctx_ insn->pos, "cast loses sign");
			return;
		}
		if (new < old) {
			warning(sctx_ insn->pos, "cast drops bits");
			return;
		}
		if (oldsigned == newsigned) {
			warning(sctx_ insn->pos, "cast wasn't removed");
			return;
		}
		warning(sctx_ insn->pos, "cast changes sign");
	}
}

static void check_range_instruction(SCTX_ struct instruction *insn)
{
	warning(sctx_ insn->pos, "value out of range");



( run in 1.249 second using v1.01-cache-2.11-cpan-71847e10f99 )