1 // RUN: %clang_cc1 -fsyntax-only -Wformat -verify %s -Wno-error=non-pod-varargs
2 // RUN: %clang_cc1 -fsyntax-only -Wformat -verify -std=c++98 %s -Wno-error=non-pod-varargs
3 // RUN: %clang_cc1 -fsyntax-only -Wformat -verify -std=c++11 %s -Wno-error=non-pod-varargs
4
5 #include <stdarg.h>
6
7 extern "C" {
8 extern int printf(const char *restrict, ...);
9 extern int sprintf(char *, const char *restrict, ...);
10 }
11
12 class HasCStr {
13 const char *str;
14 public:
HasCStr(const char * s)15 HasCStr(const char *s): str(s) { }
c_str()16 const char *c_str() {return str;}
17 };
18
19 class HasNoCStr {
20 const char *str;
21 public:
HasNoCStr(const char * s)22 HasNoCStr(const char *s): str(s) { }
not_c_str()23 const char *not_c_str() {return str;}
24 };
25
26 extern const char extstr[16];
pod_test()27 void pod_test() {
28 char str[] = "test";
29 char dest[32];
30 char formatString[] = "non-const %s %s";
31 HasCStr hcs(str);
32 HasNoCStr hncs(str);
33 int n = 10;
34
35 printf("%d: %s\n", n, hcs.c_str());
36 printf("%d: %s\n", n, hcs);
37 #if __cplusplus <= 199711L
38 // expected-warning@-2 {{cannot pass non-POD object of type 'HasCStr' to variadic function; expected type from format string was 'char *'}}
39 // expected-note@-3 {{did you mean to call the c_str() method?}}
40 #else
41 // expected-warning@-5 {{format specifies type 'char *' but the argument has type 'HasCStr'}}
42 #endif
43
44 printf("%d: %s\n", n, hncs);
45 #if __cplusplus <= 199711L
46 // expected-warning@-2 {{cannot pass non-POD object of type 'HasNoCStr' to variadic function; expected type from format string was 'char *'}}
47 #else
48 // expected-warning@-4 {{format specifies type 'char *' but the argument has type 'HasNoCStr'}}
49 #endif
50
51 sprintf(str, "%d: %s", n, hcs);
52 #if __cplusplus <= 199711L
53 // expected-warning@-2 {{cannot pass non-POD object of type 'HasCStr' to variadic function; expected type from format string was 'char *'}}
54 // expected-note@-3 {{did you mean to call the c_str() method?}}
55 #else
56 // expected-warning@-5 {{format specifies type 'char *' but the argument has type 'HasCStr'}}
57 #endif
58
59 printf(formatString, hcs, hncs);
60 #if __cplusplus <= 199711L
61 // expected-warning@-2 {{cannot pass object of non-POD type 'HasCStr' through variadic function}}
62 // expected-warning@-3 {{cannot pass object of non-POD type 'HasNoCStr' through variadic function}}
63 #endif
64
65 printf(extstr, hcs, n);
66 #if __cplusplus <= 199711L
67 // expected-warning@-2 {{cannot pass object of non-POD type 'HasCStr' through variadic function}}
68 #endif
69 }
70
71 struct Printf {
72 Printf();
73 Printf(const Printf&);
74 Printf(const char *,...) __attribute__((__format__(__printf__,2,3)));
75 };
76
constructor_test()77 void constructor_test() {
78 const char str[] = "test";
79 HasCStr hcs(str);
80 Printf p("%s %d %s", str, 10, 10); // expected-warning {{format specifies type 'char *' but the argument has type 'int'}}
81 Printf q("%s %d", hcs, 10);
82 #if __cplusplus <= 199711L
83 // expected-warning@-2 {{cannot pass non-POD object of type 'HasCStr' to variadic constructor; expected type from format string was 'char *'}}
84 // expected-note@-3 {{did you mean to call the c_str() method?}}
85 #else
86 // expected-warning@-5 {{format specifies type 'char *' but the argument has type 'HasCStr'}}
87 #endif
88 }
89