1831421f24057b93ea28bc92d8bd6290631a43cafRichard Smith// RUN: %clang_cc1 -fsyntax-only -Wformat -verify %s -Wno-error=non-pod-varargs 2831421f24057b93ea28bc92d8bd6290631a43cafRichard Smith 3831421f24057b93ea28bc92d8bd6290631a43cafRichard Smith#include <stdarg.h> 4831421f24057b93ea28bc92d8bd6290631a43cafRichard Smith 5831421f24057b93ea28bc92d8bd6290631a43cafRichard Smithextern "C" { 6831421f24057b93ea28bc92d8bd6290631a43cafRichard Smithextern int printf(const char *restrict, ...); 7831421f24057b93ea28bc92d8bd6290631a43cafRichard Smithextern int sprintf(char *, const char *restrict, ...); 8831421f24057b93ea28bc92d8bd6290631a43cafRichard Smith} 9831421f24057b93ea28bc92d8bd6290631a43cafRichard Smith 10831421f24057b93ea28bc92d8bd6290631a43cafRichard Smithclass HasCStr { 11831421f24057b93ea28bc92d8bd6290631a43cafRichard Smith const char *str; 12831421f24057b93ea28bc92d8bd6290631a43cafRichard Smith public: 13831421f24057b93ea28bc92d8bd6290631a43cafRichard Smith HasCStr(const char *s): str(s) { } 14831421f24057b93ea28bc92d8bd6290631a43cafRichard Smith const char *c_str() {return str;} 15831421f24057b93ea28bc92d8bd6290631a43cafRichard Smith}; 16831421f24057b93ea28bc92d8bd6290631a43cafRichard Smith 17831421f24057b93ea28bc92d8bd6290631a43cafRichard Smithclass HasNoCStr { 18831421f24057b93ea28bc92d8bd6290631a43cafRichard Smith const char *str; 19831421f24057b93ea28bc92d8bd6290631a43cafRichard Smith public: 20831421f24057b93ea28bc92d8bd6290631a43cafRichard Smith HasNoCStr(const char *s): str(s) { } 21831421f24057b93ea28bc92d8bd6290631a43cafRichard Smith const char *not_c_str() {return str;} 22831421f24057b93ea28bc92d8bd6290631a43cafRichard Smith}; 23831421f24057b93ea28bc92d8bd6290631a43cafRichard Smith 24831421f24057b93ea28bc92d8bd6290631a43cafRichard Smithextern const char extstr[16]; 25831421f24057b93ea28bc92d8bd6290631a43cafRichard Smithvoid pod_test() { 26831421f24057b93ea28bc92d8bd6290631a43cafRichard Smith char str[] = "test"; 27831421f24057b93ea28bc92d8bd6290631a43cafRichard Smith char dest[32]; 28831421f24057b93ea28bc92d8bd6290631a43cafRichard Smith char formatString[] = "non-const %s %s"; 29831421f24057b93ea28bc92d8bd6290631a43cafRichard Smith HasCStr hcs(str); 30831421f24057b93ea28bc92d8bd6290631a43cafRichard Smith HasNoCStr hncs(str); 31831421f24057b93ea28bc92d8bd6290631a43cafRichard Smith int n = 10; 32831421f24057b93ea28bc92d8bd6290631a43cafRichard Smith 33831421f24057b93ea28bc92d8bd6290631a43cafRichard Smith printf("%d: %s\n", n, hcs.c_str()); 34831421f24057b93ea28bc92d8bd6290631a43cafRichard Smith printf("%d: %s\n", n, hcs); // expected-warning{{cannot pass non-POD object of type 'HasCStr' to variadic function; expected type from format string was 'char *'}} expected-note{{did you mean to call the c_str() method?}} 35831421f24057b93ea28bc92d8bd6290631a43cafRichard Smith printf("%d: %s\n", n, hncs); // expected-warning{{cannot pass non-POD object of type 'HasNoCStr' to variadic function; expected type from format string was 'char *'}} 36831421f24057b93ea28bc92d8bd6290631a43cafRichard Smith sprintf(str, "%d: %s", n, hcs); // expected-warning{{cannot pass non-POD object of type 'HasCStr' to variadic function; expected type from format string was 'char *'}} expected-note{{did you mean to call the c_str() method?}} 37831421f24057b93ea28bc92d8bd6290631a43cafRichard Smith 38831421f24057b93ea28bc92d8bd6290631a43cafRichard Smith printf(formatString, hcs, hncs); // expected-warning{{cannot pass object of non-POD type 'HasCStr' through variadic function}} expected-warning{{cannot pass object of non-POD type 'HasNoCStr' through variadic function}} 39831421f24057b93ea28bc92d8bd6290631a43cafRichard Smith printf(extstr, hcs, n); // expected-warning{{cannot pass object of non-POD type 'HasCStr' through variadic function}} 40831421f24057b93ea28bc92d8bd6290631a43cafRichard Smith} 41831421f24057b93ea28bc92d8bd6290631a43cafRichard Smith 42831421f24057b93ea28bc92d8bd6290631a43cafRichard Smithstruct Printf { 43831421f24057b93ea28bc92d8bd6290631a43cafRichard Smith Printf(); 44831421f24057b93ea28bc92d8bd6290631a43cafRichard Smith Printf(const Printf&); 45831421f24057b93ea28bc92d8bd6290631a43cafRichard Smith Printf(const char *,...) __attribute__((__format__(__printf__,2,3))); 46831421f24057b93ea28bc92d8bd6290631a43cafRichard Smith}; 47831421f24057b93ea28bc92d8bd6290631a43cafRichard Smith 48831421f24057b93ea28bc92d8bd6290631a43cafRichard Smithvoid constructor_test() { 49831421f24057b93ea28bc92d8bd6290631a43cafRichard Smith const char str[] = "test"; 50831421f24057b93ea28bc92d8bd6290631a43cafRichard Smith HasCStr hcs(str); 51831421f24057b93ea28bc92d8bd6290631a43cafRichard Smith Printf p("%s %d %s", str, 10, 10); // expected-warning {{format specifies type 'char *' but the argument has type 'int'}} 52ddcfbc9ad1817f545610999d655ac6c28d4c0c12Jordan Rose Printf q("%s %d", hcs, 10); // expected-warning {{cannot pass non-POD object of type 'HasCStr' to variadic constructor; expected type from format string was 'char *'}} expected-note{{did you mean to call the c_str() method?}} 53831421f24057b93ea28bc92d8bd6290631a43cafRichard Smith} 54