The code is as follow: struct T; template <typename U> void f() { try {} catch(T const &) {} } struct T {}; int main() { f<int>(); return 0; } g++ accepts, but clang++ rejects it: code0.cpp:8:17: error: cannot catch reference to incomplete type 'const T' catch(T const &) ^ code0.cpp:1:8: note: forward declaration of 'T' struct T; ^ 1 error generated. 15.3 Handling an exception [except.handle] 1 The exception-declaration in a handler describes the type(s) of exceptions that can cause that handler to be entered. The exception-declaration shall not denote an incomplete type or an rvalue reference type. The exception-declaration shall not denote a pointer or reference to an incomplete type, other than void*, const void*, volatile void*, or const volatile void*.
This might depend on the point of instantiation of the function template. The type is complete when the template is instantiated (although T is not dependent in the template body, so maybe it should be diagnosed earlier).