Format strings: offer a cast to 'unichar' for %C in Objective-C contexts.
For most cases where a conversion specifier doesn't match an argument,
we usually guess that the conversion specifier is wrong. However, if
the argument is an integer type and the specifier is %C, it's likely
the user really did mean to print the integer as a character.
(This is more common than %c because there is no way to specify a unichar
literal -- you have to write an integer literal, such as '0x2603',
and then cast it to unichar.)
This does not change the behavior of %S, since there are fewer cases
where printing a literal Unicode *string* is necessary, but this could
easily be changed in the future.
<rdar://problem/11982013>
llvm-svn: 169400
diff --git a/clang/lib/Analysis/PrintfFormatString.cpp b/clang/lib/Analysis/PrintfFormatString.cpp
index 0820791..176aaed 100644
--- a/clang/lib/Analysis/PrintfFormatString.cpp
+++ b/clang/lib/Analysis/PrintfFormatString.cpp
@@ -359,17 +359,19 @@
case ConversionSpecifier::sArg:
if (LM.getKind() == LengthModifier::AsWideChar) {
if (IsObjCLiteral)
- return Ctx.getPointerType(Ctx.UnsignedShortTy.withConst());
+ return ArgType(Ctx.getPointerType(Ctx.UnsignedShortTy.withConst()),
+ "const unichar *");
return ArgType(ArgType::WCStrTy, "wchar_t *");
}
return ArgType::CStrTy;
case ConversionSpecifier::SArg:
if (IsObjCLiteral)
- return Ctx.getPointerType(Ctx.UnsignedShortTy.withConst());
+ return ArgType(Ctx.getPointerType(Ctx.UnsignedShortTy.withConst()),
+ "const unichar *");
return ArgType(ArgType::WCStrTy, "wchar_t *");
case ConversionSpecifier::CArg:
if (IsObjCLiteral)
- return Ctx.UnsignedShortTy;
+ return ArgType(Ctx.UnsignedShortTy, "unichar");
return ArgType(Ctx.WCharTy, "wchar_t");
case ConversionSpecifier::pArg:
return ArgType::CPointerTy;