// RUN: %clang_cc1 -fsyntax-only -verify -Wformat-nonliteral -pedantic %s #include extern "C" { extern int scanf(const char *restrict, ...); extern int printf(const char *restrict, ...); extern int vprintf(const char *restrict, va_list); } @class NSString; @interface Format + (void)print:(NSString *)format, ... __attribute__((format(NSString, 1, 2))); @end namespace Templates { template void my_uninstantiated_print(const T &arg) { [Format print:@"%d", arg]; } template void my_print(const T &arg) { [Format print:@"%d", arg]; // expected-warning {{format specifies type 'int' but the argument has type 'const char *'}} } void use_my_print() { my_print("abc"); // expected-note {{requested here}} } template class UninstantiatedPrinter { public: static void print(const T &arg) { [Format print:@"%d", arg]; // no-warning } }; template class Printer { public: void print(const T &arg) { [Format print:@"%d", arg]; // expected-warning {{format specifies type 'int' but the argument has type 'const char *'}} } }; void use_class(Printer &p) { p.print("abc"); // expected-note {{requested here}} } template class UninstantiatedWrapper { public: class Printer { public: void print(const T &arg) { [Format print:@"%d", arg]; // no-warning } }; }; template class Wrapper { public: class Printer { public: void print(const T &arg) { [Format print:@"%d", arg]; // expected-warning {{format specifies type 'int' but the argument has type 'const char *'}} } }; }; void use_class(Wrapper::Printer &p) { p.print("abc"); // expected-note {{requested here}} } }