Variable shadowing warnings in GCC (-Wshadow) and Go's vet tool implement precisely the scope-stack analysis you are writing; Go famously made shadowing with := a recurring source of production bugs. Rust turned shadowing into a feature, but only because its compiler tracks scopes precisely enough to make it safe.