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: 15 HasCStr(const char *s): str(s) { } 16 const char *c_str() {return str;} 17 }; 18 19 class HasNoCStr { 20 const char *str; 21 public: 22 HasNoCStr(const char *s): str(s) { } 23 const char *not_c_str() {return str;} 24 }; 25 26 extern const char extstr[16]; 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 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