| // 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 <stdarg.h> | 
 |  | 
 | 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 | 
 | } |