llvm-project/clang/test/SemaCXX/printf-cstr.cpp
Jordan Rose 3e0ec58c09 For varargs, diagnose passing ObjC objects by value like other non-POD types.
While we still want to consider this a hard error (non-POD variadic args are
normally a DefaultError warning), delaying the diagnostic allows us to give
better error messages, which also match the usual non-POD errors more closely.

In addition, this change improves the diagnostic messages for format string
argument type mismatches by passing down the type of the callee, so we can
say "variadic method" or "variadic function" appropriately.

<rdar://problem/11825593>

llvm-svn: 160517
2012-07-19 18:10:23 +00:00

54 lines
2.2 KiB
C++

// RUN: %clang_cc1 -fsyntax-only -Wformat -verify %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); // 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?}}
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 *'}}
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?}}
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}}
printf(extstr, hcs, n); // expected-warning{{cannot pass object of non-POD type 'HasCStr' through variadic function}}
}
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); // 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?}}
}