Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Facts involving constants don't propagate to bounds checks #5

Closed
mvdan opened this issue Mar 24, 2018 · 4 comments
Closed

Facts involving constants don't propagate to bounds checks #5

mvdan opened this issue Mar 24, 2018 · 4 comments

Comments

@mvdan
Copy link

mvdan commented Mar 24, 2018

Apologies if this bug report is lacking any information or if I missed anything obvious. But I've been playing with this for over twenty minutes, and I cannot figure it out.

I have a piece of code:

pri const maxBlockSize u32 = 128 << 10 // 128KiB
[...]
var blockSize u32 = [...]
[...]
var i u32
while i < blockSize, inv blockSize <= maxBlockSize {
        assert i <= maxBlockSize via "a <= b: a <= c; c <= b"(c:blockSize)
        i += 1
}

And this gets an error:

check: assignment "i += 1" bounds [1..4294967296] is not within bounds [0..4294967295] at decode.wuffs:87. Facts:
        blockSize <= maxBlockSize
        i < blockSize
        i <= maxBlockSize

It seems to me like from those facts, I should be able to prove that i <= 131072, since 131072 == maxBlockSize and i <= maxBlockSize. However, I don't seem to be able to. I have tried multiple asserts, including assert maxBlockSize == 131072 and assert i <= 131072 via "a <= b: a <= c; c == b"(c:maxBlockSize).

Here's why I think this is a bug in Wuffs - if I replace all uses of maxBlockSize with 131072, the bounds error disappears.

@mvdan
Copy link
Author

mvdan commented Mar 24, 2018

If you want to reproduce this:

git clone https://github.com/mvdan/zstd
git checkout tmp-break-inv
./build

The HEAD commit in that branch is what replaces the number with the constant name.

@mvdan
Copy link
Author

mvdan commented Mar 31, 2018

Thanks for the fix!

@mvdan
Copy link
Author

mvdan commented Mar 31, 2018

@nigeltao playing with this new feature, I hit a fun "cannot prove" error:

check: cannot prove "i <= 131072": cannot prove "block_size <= 131072": failed at decode.wuffs:86. Facts:
        max_block_size == 131072
        block_size <= max_block_size
        i < block_size

The code in question looks like:

var i u32
while i < block_size,
        inv max_block_size == 131072,
        inv block_size <= max_block_size {
        assert i <= max_block_size via "a <= b: a <= c; c <= b"(c:block_size)
        i += 1
}

Shouldn't this work? Or what am I missing?

@mvdan
Copy link
Author

mvdan commented Mar 31, 2018

Ignore my comment above - I wasn't actually running the compiler on that assertion.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant