Open
Description
Consider the following code:
uint32_t bext(uint32_t rs1, uint32_t rs2)
{
uint32_t c = 0, m = 1, mask = rs2;
int iter = 0;
while (mask)
{
assert(iter != 32);
iter++;
uint32_t b = mask & -mask;
if (rs1 & b)
c |= m;
mask -= b;
m <<= 1;
}
return c;
}
cbmc will unwind that loop forever.
Adding the following (unreachable) return will fix unwinding and cbmc will correctly verify the assertion:
uint32_t bext(uint32_t rs1, uint32_t rs2)
{
uint32_t c = 0, m = 1, mask = rs2;
int iter = 0;
while (mask)
{
assert(iter != 32);
if (iter == 32) return; // <-- stop unwinding if assertion failed
iter++;
uint32_t b = mask & -mask;
if (rs1 & b)
c |= m;
mask -= b;
m <<= 1;
}
return c;
}
I think assert(x);
should be treated like if (!x) return;
for the purpose of loop unwinding. There is nothing to gain from unwinding a loop beyond a failed assertion.
Metadata
Metadata
Assignees
Labels
No labels