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 )