Clang can't catch this one yet, at least not as part of compiling (I haven't checked the clang static analyzer, and if it also can't, please file a bug).
GCC has decided that it's okay to emit warnings from the middle of the optimizer:
$ g++ -Waggressive-loop-optimizations a.cc
$ g++ -Waggressive-loop-optimizations a.cc -O2
a.cc: In function ‘int main()’:
a.cc:6:5: warning: iteration 2147483647u invokes undefined behavior [-Waggressive-loop-optimizations]
for (int i(0); i != n; ++i)
^
a.cc:6:5: note: containing loop
This is actually really tricky and potentially finicky. The clang developers believe that changing what warnings you emit based on optimization level is bad behaviour, we don't think users expect to miss warnings when building at -O0 or to discover new bugs days later when doing a release build. Secondly, the way that the optimizer is designed is such that it keeps one representation of the program around at any point in time and transforms it from saying one thing to another without keeping a history trail of what it's done versus what's in the original code. This LLVM blog article talks about the problem. Clang's warnings are built on top of clang's ASTs which have a complete representation of the original source code, including template and macro histories so we can always point to the right code and filter on properties like "was it a template argument".
It might be possible to add this to clang, I haven't figured out an efficient way to do it after only 30 seconds of thinking about it. The problem is that we're willing to spend a lot more time proving things in the optimizer than we are as part of warning generation. We don't want to pay the compile time twice. The static analyzer on the other hand, doesn't have this restriction and will happily do very expensive work to find your bugs.
Finally, the way you phrased your question makes it sound like you think that clang either does or doesn't catch all undefined behaviour at compile time. We do catch as much as we can efficiently, and provide dynamic checkers for as much of the rest as possible, but neither gcc nor clang will promise to catch all undefined behaviour either at compile time nor at run time. There's too much of it, and there is no list of what it all is (some operations are explicitly UB in the standard, some are UB simply because the standard fails to define what the behaviour is!).