https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89800
Bug ID: 89800 Summary: -Waggressive-loop-optimization warning doesn't have useful location Product: gcc Version: 9.0 Status: UNCONFIRMED Keywords: diagnostic Severity: normal Priority: P3 Component: tree-optimization Assignee: unassigned at gcc dot gnu.org Reporter: redi at gcc dot gnu.org Target Milestone: --- Given: template<typename T> T foo(T t, int n) { while (n--) ++t; return t; } int bar(int n) { return foo(1, n); } int main() { return bar(-1); } GCC prints: loop.cc: In function 'int main()': loop.cc:4:3: warning: iteration 2147483647 invokes undefined behavior [-Waggressive-loop-optimizations] 4 | while (n--) | ^~~~~ loop.cc:4:3: note: within this loop This isn't very helpful, because the loop isn't in the function 'int main()' as shown, it's in foo, and there's no indication of how foo was called from main (there could be several different places in main that indirectly end up calling foo). I would expect to see something more like: loop.cc:4:3: warning: iteration 2147483647 invokes undefined behavior [-Waggressive-loop-optimizations] 4 | while (n--) | ^~~~~ loop.cc:4:3: note: within this loop loop.cc:2:1 In instantiation of 'foo<T>(T, int) [with T = int]': loop.cc:9:25 required from 'int bar(int)': loop.cc:13:10: required from here A more realistic example is: #include <array> #include <forward_list> #include <iterator> template<typename T> typename T::value_type back(const T& t) { return *std::prev(t.end()); } int main() { std::array<int, 2> a = { {1, 2} }; std::forward_list<int> l = {1, 2, 3}; return back(a) - back(l); } With -Wall -Wsystem-headers -O1 this prints: In file included from /home/jwakely/gcc/9/include/c++/9.0.1/bits/stl_algobase.h:66, from /home/jwakely/gcc/9/include/c++/9.0.1/bits/char_traits.h:39, from /home/jwakely/gcc/9/include/c++/9.0.1/string:40, from /home/jwakely/gcc/9/include/c++/9.0.1/stdexcept:39, from /home/jwakely/gcc/9/include/c++/9.0.1/array:39, from prev.cc:1: /home/jwakely/gcc/9/include/c++/9.0.1/bits/stl_iterator_base_funcs.h: In function 'int main()': /home/jwakely/gcc/9/include/c++/9.0.1/bits/stl_iterator_base_funcs.h:153:7: warning: iteration 9223372036854775806 invokes undefined behavior [-Waggressive-loop-optimizations] 153 | while (__n--) | ^~~~~ /home/jwakely/gcc/9/include/c++/9.0.1/bits/stl_iterator_base_funcs.h:153:7: note: within this loop The only location info is the "In file included from" which only shows the header include stack and the lines of the #include directives, not the call stack that reached std::__advance where the UB is detected. The headers suggest that it maybe came from the <array> header, but the back(a) call is fine, the problem is the back(l) call. (The reason is shows the array header is that that's the route by which the <bits/stl_iterator_base_funcs.h> header gets included, but is not the call stack for the undefined call). To be useful the warning needs to show the template instantiation context, something like: void std::__advance<_InputIterator, _Distance>(_InputIterator&, _Distance, input_iterator_tag) [with _InputIterator = std::forward_list<int>::const_iterator, _Distance = int] void std::advance<_InputIterator, _Distance>(_InputIterator&, _Distance) [with _InputIterator = std::forward_list<int>::const_iterator, _Distance = int] void std::prev<_BidirectionalIterator>(_BidirectionalIterator&, ...) [with _BidirectionalIterator = std::forward_list<int>::const_iterator] T::value_type back(const T&) [with T = std::forward_list<int>] prev.cc:16:20 required from here return back(a) - back(l); ^^^^^^^ This allows the user to see how the undefined behaviour happened. (As an aside, should it say "results in undefined behavior" or "has undefined behavior" not "invokes undefined behavior"? You don't invoke UB, it's not a function.)