|
1 |
| -// RUN: %clang_cc1 -fsyntax-only -verify -Wformat-nonliteral -isystem %S/Inputs %s |
2 |
| -// RUN: %clang_cc1 -fsyntax-only -verify -Wformat-nonliteral -isystem %S/Inputs -fno-signed-char %s |
| 1 | +// RUN: %clang_cc1 -fblocks -fsyntax-only -verify -Wformat-nonliteral -isystem %S/Inputs %s |
| 2 | +// RUN: %clang_cc1 -fblocks -fsyntax-only -verify -Wformat-nonliteral -isystem %S/Inputs -fno-signed-char %s |
3 | 3 |
|
4 | 4 | #include <stdarg.h>
|
5 | 5 | #include <stddef.h>
|
@@ -714,3 +714,30 @@ void PR30481() {
|
714 | 714 | void test_printf_opaque_ptr(void *op) {
|
715 | 715 | printf("%s", op); // expected-warning{{format specifies type 'char *' but the argument has type 'void *'}}
|
716 | 716 | }
|
| 717 | + |
| 718 | +void test_block() { |
| 719 | + void __attribute__((__format__(__printf__, 1, 2))) (^printf_arg1)( |
| 720 | + const char *, ...) = |
| 721 | + ^(const char *fmt, ...) __attribute__((__format__(__printf__, 1, 2))) { |
| 722 | + va_list ap; |
| 723 | + va_start(ap, fmt); |
| 724 | + vprintf(fmt, ap); |
| 725 | + va_end(ap); |
| 726 | + }; |
| 727 | + |
| 728 | + printf_arg1("%s string %i\n", "aaa", 123); |
| 729 | + printf_arg1("%s string\n", 123); // expected-warning{{format specifies type 'char *' but the argument has type 'int'}} |
| 730 | + |
| 731 | + void __attribute__((__format__(__printf__, 2, 3))) (^printf_arg2)( |
| 732 | + const char *, const char *, ...) = |
| 733 | + ^(const char *not_fmt, const char *fmt, ...) |
| 734 | + __attribute__((__format__(__printf__, 2, 3))) { |
| 735 | + va_list ap; |
| 736 | + va_start(ap, fmt); |
| 737 | + vprintf(not_fmt, ap); // expected-warning{{format string is not a string literal}} |
| 738 | + va_end(ap); |
| 739 | + }; |
| 740 | + |
| 741 | + printf_arg2("foo", "%s string %i\n", "aaa", 123); |
| 742 | + printf_arg2("%s string\n", "foo", "bar"); // expected-warning{{data argument not used by format string}} |
| 743 | +} |
0 commit comments