https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115870
Bug ID: 115870 Summary: Inlining of a template function leads to infinite loop Product: gcc Version: 12.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: Manuel.Demmeler at kuka dot com Target Milestone: --- Created attachment 58635 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=58635&action=edit Preprocessed file from "/usr/bin/gcc -save-temps -Wall -O2 -g -Wextra -o out/main main.cpp" The minimal example below compiled with ``` /usr/bin/gcc -save-temps -Wall -O2 -g -Wextra -o out/main main.cpp ``` produces an endless loop when executing the program and the following compilation output: ``` In member function 'int CArray<N>::foo(int, int) const [with int N = 10]', inlined from 'int CArray<N>::foo(int, int) const [with int N = 11]' at main.cpp:24:8, inlined from 'int main()' at main.cpp:49:23: main.cpp:30:10: warning: iteration 10 invokes undefined behavior [-Waggressive-loop-optimizations] 30 | for (int idx{0U}; idx < num; ++idx) | ^~~ main.cpp:30:32: note: within this loop 30 | for (int idx{0U}; idx < num; ++idx) | ~~~~^~~~~ ``` It looks like the compiler confuses the different instances of the template function for parameters N = 10 and 11. Further, if using int_type = uint32_t, the above warning is missing and the endless loop is still produced. Note that the endless loop can also easily be seen in the assembler output: https://godbolt.org/z/9P8bY3TK6 main.cpp: ``` #include <cstdint> using int_type = int; int_type bar(uint8_t const * const s, int_type const len) { return s[0] + s[len-1]; } template<int_type N> class CArray final { public: // (......) int_type foo(int_type const initialValue, int_type const num) const { int_type retVal{initialValue}; if (num <= N) { for (int_type idx{0U}; idx < num; ++idx) { retVal += bar(reinterpret_cast<uint8_t const *>(&m_values[idx]), sizeof(int_type)); } } return retVal; } private: int_type m_values[N]{}; }; int main() { CArray<10U> array1{}; CArray<11U> array2{}; int_type foo1{array1.foo(1U, 10U)}; int_type foo2{array2.foo(1U, 11U)}; return foo1 + foo2; } ``` Used version: g++ (Debian 12.2.0-14) 12.2.0