Yes, runtime errors that are environmental cannot be caught at compile time. But many other runtime errors are the result of design errors - designs that lead to more possible mistakes. When given a bit of thought, you can make those errors get flagged at compile time.
For example, the classic criticism of C++'s resource management. C++ doesn't have those problems if people used the RAII that's provided by default. You don't need to analyze for leaks or null pointers if those cost-free features (which are also semantic signals) are used. And by leaks, even stuff like managing database resources can be taken care of by RAII, leading to reduced environmental errors that may lead to things like duplicate primary keys being created.
Static analysis tools are okay if it comes to snippets of code changes, but can't tell you much about design flaws. I too often see people making local changes to "fix" the error when they should have given more thought about reorganizing even just the code of that function a bit. The other thing that is popular these days in C++ are generic algorithms. The properties of generic algorithms are known, including the elimination of most range errors. Static analysis doesn't tell you that you should replace your hand-crafted for loop (or thread synchronization) to use a more suitable higher level construct. In Java, that may as well be a good thing, since high level implies efficiency cost in a way C++ generic high level constructs don't.