The code is the following:
#include <cstdint>
#include <iostream>
using u64 = std::uint64_t;
u64 *test() {
    u64 *a, *p;
    p = (u64 *)&a;
    a = (u64 *)&p;
    {
        for (int i = 0; i < 100; ++i) {
            p = new u64((u64)p);
        }
    }
    while (true) {
        if ((u64)p == 0) {
            break;
        }
        p = (u64 *)*p;
    }
    return p;
}
int main() {
    std::cout << test() << std::endl;
}
And the compiled asm of function test is the following:
test():
        xor     eax, eax
        ret
You can see https://godbolt.org/z/8eTd8WMzG.
In fact, it's expected when the final stmt is return a; although the compiler tells a warning about retuning a local address. And if I make a and p being global variables, everything is ok, see https://godbolt.org/z/n7YWzGvd5.
So, I think that maybe I face some ubs so that its behavior not match my expectation?
 
     
    