1 // RUN: %clang_cc1 -fsyntax-only -verify -Wformat-nonliteral -pedantic %s 2 3 #include <stdarg.h> 4 5 extern "C" { 6 extern int scanf(const char *restrict, ...); 7 extern int printf(const char *restrict, ...); 8 extern int vprintf(const char *restrict, va_list); 9 } 10 11 @class NSString; 12 13 @interface Format 14 + (void)print:(NSString *)format, ... __attribute__((format(NSString, 1, 2))); 15 @end 16 17 18 namespace Templates { 19 template<typename T> 20 void my_uninstantiated_print(const T &arg) { 21 [Format print:@"%d", arg]; 22 } 23 24 template<typename T> 25 void my_print(const T &arg) { 26 [Format print:@"%d", arg]; // expected-warning {{format specifies type 'int' but the argument has type 'const char *'}} 27 } 28 29 void use_my_print() { 30 my_print("abc"); // expected-note {{requested here}} 31 } 32 33 34 template<typename T> 35 class UninstantiatedPrinter { 36 public: 37 static void print(const T &arg) { 38 [Format print:@"%d", arg]; // no-warning 39 } 40 }; 41 42 template<typename T> 43 class Printer { 44 public: 45 void print(const T &arg) { 46 [Format print:@"%d", arg]; // expected-warning {{format specifies type 'int' but the argument has type 'const char *'}} 47 } 48 }; 49 50 void use_class(Printer<const char *> &p) { 51 p.print("abc"); // expected-note {{requested here}} 52 } 53 54 55 template<typename T> 56 class UninstantiatedWrapper { 57 public: 58 class Printer { 59 public: 60 void print(const T &arg) { 61 [Format print:@"%d", arg]; // no-warning 62 } 63 }; 64 }; 65 66 template<typename T> 67 class Wrapper { 68 public: 69 class Printer { 70 public: 71 void print(const T &arg) { 72 [Format print:@"%d", arg]; // expected-warning {{format specifies type 'int' but the argument has type 'const char *'}} 73 } 74 }; 75 }; 76 77 void use_class(Wrapper<const char *>::Printer &p) { 78 p.print("abc"); // expected-note {{requested here}} 79 } 80 } 81 82