Clang (and gcc and comeau) accept the following invalid program: static void test1(int *) { } template<typename T> int *test2(const T &) { return 0; } template<typename T> void test3(const T &t) { test1(test2(t)); } The statement "test1(test2(t))" is type-dependent all the way through to test1. 14.6.4.2/1 second bullet states: "For the part of the lookup using associated namespace (3.4.2), only function declarations with external linkage found in either the template definition context or the template instantiation context are found." test1() does not have external linkage. If we remove 'static' or change test1 to ::test1 (see the rest of the referenced section) then the program becomes valid.
(In reply to comment #0) > Clang (and gcc and comeau) accept the following invalid program: > > static void test1(int *) { } > > template<typename T> > int *test2(const T &) { return 0; } > > template<typename T> > void test3(const T &t) { > test1(test2(t)); > } > > The statement "test1(test2(t))" is type-dependent all the way through to test1. > 14.6.4.2/1 second bullet states: > "For the part of the lookup using associated namespace (3.4.2), only function > declarations with external linkage found in either the template definition > context or the template instantiation context are found." Just to clarify, the first bullet is the one that governs from 14.6.4.2/1, but it too restricts to functions with external linkage. > > test1() does not have external linkage. If we remove 'static' or change test1 > to ::test1 (see the rest of the referenced section) then the program becomes > valid.
And this is fixed in C++0x, which says: "— For the part of the lookup using unqualified name lookup (3.4.1), only function declarations from the template definition context are found. — For the part of the lookup using associated namespaces (3.4.2), only function declarations found in either the template definition context or the template instantiation context are found. "
This was CWG issue 561, and I think it's reasonable to consider this a bug in C++98 rather than a bug in Clang :)