aptos-labs / aptos-core

Aptos is a layer 1 blockchain built to support the widespread use of blockchain through better technology and user experience.
https://aptosfoundation.org
Other
6.18k stars 3.66k forks source link

[Bug][move-compiler] V2 does not warn semantic difference #14588

Open zzjas opened 2 months ago

zzjas commented 2 months ago

🐛 Bug

//# publish
module 0xCAFE::Module0 {
    use std::vector;
    struct S has copy, drop, store, key {
        v: vector<u8>
    }

    public fun f1(s: signer) acquires S{
        move_to<S>(&s, S {v: vector::empty()});
        f2(1)
        ^ 
        if (true) {
            f2(2)
        } else { 0 };
    }

    public fun f2(x: u8): u8 acquires S {
        let s = borrow_global_mut<S>(@0xBEEF);
        vector::push_back(&mut s.v, x);
        x
    }
}

//# run 0xCAFE::Module0::f1 --signers 0xBEEF

//# view --address 0xBEEF --resource 0xCAFE::Module0::S

Running this as transactional test will give:

comparison between v1 and v2 failed:
= processed 3 tasks
= 
= task 2 'view'. lines 27-27:
= copy drop store key 0xcafe::Module0::S {
-     v: 0201
+     v: 0102
= }
=

A warning about the difference between V1 and V2 semantics is expected.

zzjas commented 2 months ago

Similar case:

//# publish
module 0xCAFE::FuzzStore {
    struct S has drop, copy, store, key {
        x: u8
    }

    fun init(s: signer) {
        move_to<S>(&s, S { x: 0 });
    }
    public fun inc() acquires S {
        let s = borrow_global_mut<S>(@0xBEEF);
        s.x = s.x + 1;
    }
}

//# run 0xCAFE::FuzzStore::init --signers 0xBEEF

//# publish
module 0xCAFE::Module0 {
    use 0xCAFE::FuzzStore::inc;
    public fun f1(): u8 {
        f2() ^ (return 123u8);
        0
    }

    public fun f2(): u8 {
        inc();
        0
    }
}

//# run 0xCAFE::Module0::f1

//# view --address 0xBEEF --resource 0xCAFE::FuzzStore::S

Transactional output:

...
= task 4 'view'. lines 34-34:
= copy drop store key 0xcafe::FuzzStore::S {
-     x: 0u8
+     x: 1u8
= }

Compiling with aptos move compile --compiler-version=2 --language-version=1 didn't give any warning.

I had to use a separate module for this one because V1 will optimize away the left operand -- making the compiler fail with extraneous acquires error.