Summary: | lang/clang35 does not handle %D formats properly | ||||||
---|---|---|---|---|---|---|---|
Product: | Ports & Packages | Reporter: | Dimitry Andric <dim> | ||||
Component: | Individual Port(s) | Assignee: | Brooks Davis <brooks> | ||||
Status: | Closed FIXED | ||||||
Severity: | Affects Some People | CC: | davide, emaste, hselasky, w.schwarzenfeld | ||||
Priority: | --- | Flags: | bugzilla:
maintainer-feedback?
(brooks) |
||||
Version: | Latest | ||||||
Hardware: | Any | ||||||
OS: | Any | ||||||
Attachments: |
|
Description
Dimitry Andric
2015-05-14 16:13:30 UTC
The minimal example produces the wrong result, but does not fail as described. [bed22@vica ~]$ cat format-D.c void foo(int, const char *, ...) __attribute__((__format__(__printf__, 2, 3))); void bar(const unsigned char *p, unsigned short len) { foo(-1, " %*D", len, p, "-"); } [bed22@vica ~]$ clang34 -fformat-extensions -Wall -o /dev/null -c format-D.c format-D.c:6:15: warning: format specifies type 'unsigned char *' but the argument has type 'const unsigned char *' [-Wformat] foo(-1, " %*D", len, p, "-"); ~~^ ~ 1 warning generated. [bed22@vica ~]$ clang35 -fformat-extensions -Wall -o /dev/null -c format-D.c format-D.c:6:15: warning: format specifies type 'unsigned char *' but the argument has 'const unsigned char *' [-Wformat] foo(-1, " %*D", len, p, "-"); ~~^ ~ 1 warning generated. [bed22@vica ~]$ clang36 -fformat-extensions -Wall -o /dev/null -c format-D.c format-D.c:6:15: warning: format specifies type 'unsigned char *' but the argument has 'const unsigned char *' [-Wformat] foo(-1, " %*D", len, p, "-"); ~~^ ~ 1 warning generated. clang-devel (updated a couple days ago) rejects %D entirely. [bed22@vica ~]$ clang-devel -fformat-extensions -Wall -o /dev/null -c format-D.c format-D.c:6:15: warning: invalid conversion specifier 'D' [-Wformat-invalid-specifier] foo(-1, " %*D", len, p, "-"); ~~^ format-D.c:6:19: warning: data argument not used by format string [-Wformat-extra-args] foo(-1, " %*D", len, p, "-"); ~~~~~~ ^ Should reproduce on FreeBSD-9-stable userspace with clang installed from binary PKG. --HPS (In reply to Brooks Davis from comment #1) > clang-devel (updated a couple days ago) rejects %D entirely. That's to be expected, as I committed __freebsd_kprintf__ support in upstream clang some time ago: http://reviews.llvm.org/rL229921 This is really a much better approach than a non-standard -fformat-extensions flag. In head this is already used, so I would use it instead of adding the -fformat-extensions flags, for clang 3.6.0 and higher. A better example is this, which "exercises" the specifiers a bit more: void foo(int, const char *, ...) __attribute__((__format__(__printf__, 2, 3))); void bar(const unsigned char *p, unsigned short len) { foo(-1, " %*D", len, p, "-"); foo(-1, " %*D", len, p, 42); foo(-1, " %*D", len, p); foo(-1, " %*D", len, 42, "-"); foo(-1, " %*D", len, 42); } This leads to a segfault (at least for me): $ /usr/work/share/dim/ports/lang/clang35/work/llvm-3.5.2.src/Release/bin/clang -c pr200193.c pr200193.c:5:15: warning: format specifies type 'unsigned char *' but the argument has 'const unsigned char *' [-Wformat] foo(-1, " %*D", len, p, "-"); ~~^ ~ pr200193.c:6:15: warning: format specifies type 'unsigned char *' but the argument has 'const unsigned char *' [-Wformat] foo(-1, " %*D", len, p, 42); ~~^ ~ pr200193.c:6:15: warning: format specifies type 'char *' but the argument has 'int' [-Wformat] foo(-1, " %*D", len, p, 42); ~~^ ~~ pr200193.c:7:15: warning: format specifies type 'unsigned char *' but the argument has 'const unsigned char *' [-Wformat] foo(-1, " %*D", len, p); ~~^ ~ Stack dump: 0. Program arguments: /usr/work/share/dim/ports/lang/clang35/work/llvm-3.5.2.src/Release/bin/clang -cc1 -triple i386-portbld-freebsd11.0 -emit-obj -mrelax-all -disable-free -disable-llvm-verifier -main-file-name pr200193.c -mrelocation-model static -mdisable-fp-elim -masm-verbose -mconstructor-aliases -target-cpu i486 -target-linker-version 2.25 -dwarf-column-info -coverage-file /share/dim/ports/lang/clang35/pr200193.o -resource-dir /usr/work/share/dim/ports/lang/clang35/work/llvm-3.5.2.src/Release/bin/../lib/clang/3.5.2 -fdebug-compilation-dir /share/dim/ports/lang/clang35 -ferror-limit 19 -fmessage-length 296 -mstackrealign -fobjc-runtime=gnustep -fdiagnostics-show-option -fcolor-diagnostics -o pr200193.o -x c pr200193.c 1. pr200193.c:7:25: current parser token ')' 2. pr200193.c:4:1: parsing function body 'bar' 3. pr200193.c:4:1: in compound statement ('{}') clang: error: unable to execute command: Segmentation fault clang: error: clang frontend command failed due to signal (use -v to see invocation) Created attachment 156858 [details] Updated SemaChecking.cpp patch Here is an updated patch for SemaChecking.cpp, adapted from http://reviews.llvm.org/rL229921#e3a71b9d . This also takes into account the number of remaining arguments, avoiding overruns. Patch is in the port. It is done. Can be closed. Close as requested |