|
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>
|
@@ -741,3 +741,30 @@ void PR30481() {
|
741 | 741 | void test_printf_opaque_ptr(void *op) {
|
742 | 742 | printf("%s", op); // expected-warning{{format specifies type 'char *' but the argument has type 'void *'}}
|
743 | 743 | }
|
| 744 | + |
| 745 | +void test_block() { |
| 746 | + void __attribute__((__format__(__printf__, 1, 2))) (^printf_arg1)( |
| 747 | + const char *, ...) = |
| 748 | + ^(const char *fmt, ...) __attribute__((__format__(__printf__, 1, 2))) { |
| 749 | + va_list ap; |
| 750 | + va_start(ap, fmt); |
| 751 | + vprintf(fmt, ap); |
| 752 | + va_end(ap); |
| 753 | + }; |
| 754 | + |
| 755 | + printf_arg1("%s string %i\n", "aaa", 123); |
| 756 | + printf_arg1("%s string\n", 123); // expected-warning{{format specifies type 'char *' but the argument has type 'int'}} |
| 757 | + |
| 758 | + void __attribute__((__format__(__printf__, 2, 3))) (^printf_arg2)( |
| 759 | + const char *, const char *, ...) = |
| 760 | + ^(const char *not_fmt, const char *fmt, ...) |
| 761 | + __attribute__((__format__(__printf__, 2, 3))) { |
| 762 | + va_list ap; |
| 763 | + va_start(ap, fmt); |
| 764 | + vprintf(not_fmt, ap); // expected-warning{{format string is not a string literal}} |
| 765 | + va_end(ap); |
| 766 | + }; |
| 767 | + |
| 768 | + printf_arg2("foo", "%s string %i\n", "aaa", 123); |
| 769 | + printf_arg2("%s string\n", "foo", "bar"); // expected-warning{{data argument not used by format string}} |
| 770 | +} |
0 commit comments