printf: invalid conversion specifier: 'I' when using "I64d" on Windows

Hi,

Windows’ msvcrt.dll has weird printf format strings that aren’t used anywhere else.

For example this code with Clang 3.1 on MinGW-w64 using GCC 4.6.3 libstdc++ headers:
#define __STDC_FORMAT_MACROS
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include
int main(int argc,char **argv)
{
uint64_t val=1234567890;
printf("%" PRId64"\n",val);
exit(0);
}

produces this warning:
M:\Development\x64\test>clang++ -std=c++11 test.cpp -c -Wall
test.cpp:11:15: warning: invalid conversion specifier ‘I’
[-Wformat-invalid-specifier]
printf("%" PRId64"\n",val);

M:/Development/mingw64/bin/../lib/clang/3.1/../../../x86_64-w64-mingw32/include\inttypes.h:42:17: note:
expanded from macro 'PRId64'
#define PRId64 "I64d"
^
1 warning generated.

The "I64d" form is the "correct" msvcrt printf format string for this case, and the define in the mingw-w64 header inttypes.h is used to make the code correct and thus work around the msvcrt limitations.

Clang (and don't worry, GCC too) warns on this use, while it really shouldn't, as this is correct on Windows. I understand from a MinGW-w64 dev that they annotate their printf prototype correctly, but the compiler's builtin definition conflicts with this, and hence the warning. So I think the right solution here is to allow the MS printf format strings as well. This should work for both Visual Studio based and MinGW-w64 based Clang.

I was looking through the code, and found:
[http://llvm.org/svn/llvm-project/cfe/trunk/lib/Analysis/PrintfFormatString.cpp](http://llvm.org/svn/llvm-project/cfe/trunk/lib/Analysis/PrintfFormatString.cpp)
where I think the format string is handled, because printf is defined in
[http://llvm.org/svn/llvm-project/cfe/trunk/include/clang/Basic/Builtins.def](http://llvm.org/svn/llvm-project/cfe/trunk/include/clang/Basic/Builtins.def)
as a builtin.
The warning is thrown from
[http://llvm.org/svn/llvm-project/cfe/trunk/lib/Sema/SemaChecking.cpp](http://llvm.org/svn/llvm-project/cfe/trunk/lib/Sema/SemaChecking.cpp)
as "diag::warn_format_invalid_conversion" I *think*.

Am I right that there should be a modification to PrintfFormatString.cpp (and maybe ScanfFormatString.cpp as well?) to allow the MS specific format specifiers as defined here [http://msdn.microsoft.com/en-us/library/56e442dc.aspx](http://msdn.microsoft.com/en-us/library/56e442dc.aspx) ?

I would prepare a patch, but I have no idea if the above is correct and what exactly (and how) I'd have to add this.

Therefore: any help is much appreciated!

Thanks,

Ruben

PS: please reply to my email directly as well, I'm not subscribed to cfe-dev

Interesting. Shouldn’t be too hard to add support here (conditioned on -fms-compatibility, perhaps?), and PrintfFormatString is probably the right place to do this. If you don’t feel comfortable writing a patch yourself, please file a bug at http://llvm.org/bugs/ and eventually someone will get to it. (Perhaps Hans, since he’s been doing a number of format string fixes lately?)

Thanks for catching this!
Jordan

2012/8/8 Jordan Rose <jordan_rose@apple.com>

Interesting. Shouldn’t be too hard to add support here (conditioned on -fms-compatibility, perhaps?), and PrintfFormatString is probably the right place to do this. If you don’t feel comfortable writing a patch yourself, please file a bug at http://llvm.org/bugs/ and eventually someone will get to it. (Perhaps Hans, since he’s been doing a number of format string fixes lately?)

If -fms-compatibility is enabled by default on Windows, this is fine by me. But I noticed the glibc and objc stuff is just “in plain sight” too, is this intended or just “easier to implement”?

I can take a look tomorrow and based on my findings/trials I’ll submit a bug report and/or patch :wink: Unless someone beats me to it of course…

Ruben

Not -fms-compatibility; the issue is whether the MS runtime is in use,
which is true in contexts where we don't use -fms-compatibility (like
MinGW). There are only a couple relevant target triples, though; we
can easily check for them.

-Eli

Interesting. Shouldn't be too hard to add support here (conditioned on
-fms-compatibility, perhaps?),

Not -fms-compatibility; the issue is whether the MS runtime is in use,
which is true in contexts where we don't use -fms-compatibility (like
MinGW). There are only a couple relevant target triples, though; we
can easily check for them.

Ah, I see.

2012/8/9 Jordan Rose <jordan_rose@apple.com>

No worries, thanks for the initial identification of the problem. Not sure when we'll get to it, but hopefully not too far off.

Jordan