This is an archive of the discontinued LLVM Phabricator instance.

Analysis: Add support for MS specific printf format specifiers
ClosedPublic

Authored by majnemer on Aug 21 2013, 2:01 AM.

Details

Diff Detail

Event Timeline

This is included in PR13565, so you can track your progress there.

include/clang/Analysis/Analyses/FormatString.h
77

I don't like this name. How about AsIntWord or something? (As I understand it "word" is an overloaded term in MSVC, though.)

lib/Analysis/FormatString.cpp
240

Typo: AsInt32.

544–546

Huh, I didn't realize these were present elsewhere. They don't quite behave the same on Windows, right? See http://llvm.org/bugs/show_bug.cgi?id=13565

lib/Analysis/PrintfFormatString.cpp
315

I don't know if Windows has any ILP64 configurations, but this might need to actually look for "unsigned __int32". At the very least it should use it in the name like "uintmax_t".

(I'm doing my comments backwards, so all of this applies to the signed integers as well.)

322

Ditto -- this should be "unsigned __int64".

329–332

I think just matching AsSizeT here is probably fine, per http://msdn.microsoft.com/en-us/library/tcxf1dw6(v=vs.90).aspx

371–373

It seems like all of these are valid, just not enabled by default.

lib/Analysis/ScanfFormatString.cpp
372

From what I read at http://msdn.microsoft.com/en-us/library/kwwtf9ch(v=vs.71).aspx, %I64n is technically valid.

hans added a comment.Aug 21 2013, 9:28 AM

Nice! LGTM too, just a few nits.

include/clang/Analysis/Analyses/FormatString.h
94

Looks like this needs an update too? This is used when emitting fix-it hints for replacing a length modifier.

lib/Analysis/FormatString.cpp
240

AsInt32?

718

It would be nice to have a test for the case when isOSMSVCRT() is false.

Table of format specifiers and their associated character widths with MSVCRT.DLL:

Function"%s"/"%c""%S"/"%C""%hs"/"%hc""%ls"/"%lc"
printfNarrowWideNarrowWide
wprintfWideNarrowNarrowWide
include/clang/Analysis/Analyses/FormatString.h
77

This type is in fact called __int3264 in MIDL-land.

What about AsIntPtr?

lib/Analysis/FormatString.cpp
544–546

Yeah, they don't. In fact, the behavior of these on Windows is very... uh, weird, to say the least. It depends on which function you're calling (printf or wprintf). There's a handy table above.

This is so, if you include <tchar.h> and call _tprintf, you can pass _TCHAR strings and it will behave correctly. (The macros and types in <tchar.h> behave differently depending on whether or not _UNICODE is #defined. Same for <windows.h> and UNICODE.) Note the non-standard "%hs" and "%hc" formats. They're needed because, in this scheme, there's otherwise no way to always pass a plain ol' char string!

I've addressed some of these comments inline, I will update the patch with corrections.

lib/Analysis/FormatString.cpp
544–546

They are present elsewhere, all POSIX platforms must have a 'C' and 'S' implementation that desugars to 'lc' and 'ls'

See http://pubs.opengroup.org/onlinepubs/009695399/functions/printf.html for more details.

lib/Analysis/PrintfFormatString.cpp
315

They don't have ILP64 configurations and, in fact, can't for numerous reasons relating to ABI/source compatibility. __int32 is just a synonym for int that is vended by the compiler.

329–332

I is not an analog to POSIX's z/t, it's more like their version of UNIX's variable width long type.

majnemer updated this revision to Unknown Object (????).Aug 21 2013, 2:08 PM
  • Address review feedback.
majnemer updated this revision to Unknown Object (????).Aug 21 2013, 2:43 PM
  • Further review comments.
majnemer accepted this revision.Aug 21 2013, 2:56 PM

Jordan gave the A-OK.

majnemer closed this revision.Aug 21 2013, 2:57 PM