blob: 2fb92e27560af3efbe3fdea765641030123017aa [file] [log] [blame]
Jordan Rose66360e22012-10-02 01:49:54 +00001// RUN: %clang_cc1 -fsyntax-only -verify -Wformat-nonliteral -pedantic %s
2
3#include <stdarg.h>
4
5extern "C" {
6extern int scanf(const char *restrict, ...);
7extern int printf(const char *restrict, ...);
8extern 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
18namespace 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