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