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