https://gcc.gnu.org/bugzilla/show_bug.cgi?id=121238
--- Comment #8 from Nathaniel Shead <nshead at gcc dot gnu.org> --- Thanks! That's very helpful. So here's a pretty minimal reduction from what you've shown: // format.hpp inline void inc(const char*& __first) { ++__first; } template <typename = void> bool parse_integer(const char *first) { const char *start = first; inc(first); return first != start; } inline bool works() { const char fmt[] = "5"; return parse_integer(fmt); } // mod.hpp #include "format.hpp" // main.cpp #include "format.hpp" import "mod.hpp"; int main() { if (!works()) __builtin_abort(); } $ g++ -fmodules mod.hpp main.cpp && ./a.out Aborted (core dumped) As in the other PR, gimple dump of 'parse_integer' looks wrong: bool parse_integer<> (const char * first) { const char * first.1; bool D.3010; const char * start; start = first; first.1 = first; inc (&first.1); D.3010 = first != start; return D.3010; } My immediate guess (having not really looked into this at all yet) is that we're not properly handling parameters somewhere when deduping function templates. I'll have capacity to take a look in the next couple of days, hopefully.