Bug 200193 - lang/clang35 does not handle %D formats properly
Summary: lang/clang35 does not handle %D formats properly
Status: Closed FIXED
Alias: None
Product: Ports & Packages
Classification: Unclassified
Component: Individual Port(s) (show other bugs)
Version: Latest
Hardware: Any Any
: --- Affects Some People
Assignee: Brooks Davis
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2015-05-14 16:13 UTC by Dimitry Andric
Modified: 2018-01-10 17:24 UTC (History)
4 users (show)

See Also:
bugzilla: maintainer-feedback? (brooks)


Attachments
Updated SemaChecking.cpp patch (1.92 KB, text/plain)
2015-05-17 19:23 UTC, Dimitry Andric
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Dimitry Andric freebsd_committer freebsd_triage 2015-05-14 16:13:30 UTC
Minimal example from http://llvm.org/PR23512:

void foo(int, const char *, ...) __attribute__((__format__(__printf__, 2, 3)));

void bar(const unsigned char *p, unsigned short len)
{
  foo(-1, " %*D", len, p, "-");
}

when compiled with clang 3.5.x with the -fformat-extensions flag, this either shows garbage in the warning, or even crashes.
Comment 1 Brooks Davis freebsd_committer freebsd_triage 2015-05-14 19:08:56 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, "-");
          ~~~~~~  ^
Comment 2 Hans Petter Selasky freebsd_committer freebsd_triage 2015-05-14 19:40:44 UTC
Should reproduce on FreeBSD-9-stable userspace with clang installed from binary PKG.

--HPS
Comment 3 Dimitry Andric freebsd_committer freebsd_triage 2015-05-17 16:33:47 UTC
(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.
Comment 4 Dimitry Andric freebsd_committer freebsd_triage 2015-05-17 19:19:25 UTC
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)
Comment 5 Dimitry Andric freebsd_committer freebsd_triage 2015-05-17 19:23:54 UTC
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.
Comment 6 Walter Schwarzenfeld 2018-01-10 10:49:58 UTC
Patch is in the port. It is done. Can be closed.
Comment 7 Brooks Davis freebsd_committer freebsd_triage 2018-01-10 17:24:44 UTC
Close as requested