// RUN: %clang_cc1 -fsyntax-only -Wformat -verify %s -Wno-error=non-pod-varargs // RUN: %clang_cc1 -fsyntax-only -Wformat -verify -std=c++98 %s -Wno-error=non-pod-varargs // RUN: %clang_cc1 -fsyntax-only -Wformat -verify -std=c++11 %s -Wno-error=non-pod-varargs #include extern "C" { extern int printf(const char *restrict, ...); extern int sprintf(char *, const char *restrict, ...); } class HasCStr { const char *str; public: HasCStr(const char *s): str(s) { } const char *c_str() {return str;} }; class HasNoCStr { const char *str; public: HasNoCStr(const char *s): str(s) { } const char *not_c_str() {return str;} }; extern const char extstr[16]; void pod_test() { char str[] = "test"; char dest[32]; char formatString[] = "non-const %s %s"; HasCStr hcs(str); HasNoCStr hncs(str); int n = 10; printf("%d: %s\n", n, hcs.c_str()); printf("%d: %s\n", n, hcs); #if __cplusplus <= 199711L // expected-warning@-2 {{cannot pass non-POD object of type 'HasCStr' to variadic function; expected type from format string was 'char *'}} // expected-note@-3 {{did you mean to call the c_str() method?}} #else // expected-warning@-5 {{format specifies type 'char *' but the argument has type 'HasCStr'}} #endif printf("%d: %s\n", n, hncs); #if __cplusplus <= 199711L // expected-warning@-2 {{cannot pass non-POD object of type 'HasNoCStr' to variadic function; expected type from format string was 'char *'}} #else // expected-warning@-4 {{format specifies type 'char *' but the argument has type 'HasNoCStr'}} #endif sprintf(str, "%d: %s", n, hcs); #if __cplusplus <= 199711L // expected-warning@-2 {{cannot pass non-POD object of type 'HasCStr' to variadic function; expected type from format string was 'char *'}} // expected-note@-3 {{did you mean to call the c_str() method?}} #else // expected-warning@-5 {{format specifies type 'char *' but the argument has type 'HasCStr'}} #endif printf(formatString, hcs, hncs); #if __cplusplus <= 199711L // expected-warning@-2 {{cannot pass object of non-POD type 'HasCStr' through variadic function}} // expected-warning@-3 {{cannot pass object of non-POD type 'HasNoCStr' through variadic function}} #endif printf(extstr, hcs, n); #if __cplusplus <= 199711L // expected-warning@-2 {{cannot pass object of non-POD type 'HasCStr' through variadic function}} #endif } struct Printf { Printf(); Printf(const Printf&); Printf(const char *,...) __attribute__((__format__(__printf__,2,3))); }; void constructor_test() { const char str[] = "test"; HasCStr hcs(str); Printf p("%s %d %s", str, 10, 10); // expected-warning {{format specifies type 'char *' but the argument has type 'int'}} Printf q("%s %d", hcs, 10); #if __cplusplus <= 199711L // expected-warning@-2 {{cannot pass non-POD object of type 'HasCStr' to variadic constructor; expected type from format string was 'char *'}} // expected-note@-3 {{did you mean to call the c_str() method?}} #else // expected-warning@-5 {{format specifies type 'char *' but the argument has type 'HasCStr'}} #endif }