forked from OSchip/llvm-project
Let %S, %ls, %C match 16bit types in NSStrings.
As discussed at http://lists.cs.uiuc.edu/pipermail/cfe-commits/Week-of-Mon-20120130/052200.html llvm-svn: 149325
This commit is contained in:
parent
6b68c98f7d
commit
496cdc2cb7
|
@ -455,7 +455,7 @@ public:
|
|||
/// will return null if the format specifier does not have
|
||||
/// a matching data argument or the matching argument matches
|
||||
/// more than one type.
|
||||
ArgTypeResult getArgType(ASTContext &Ctx) const;
|
||||
ArgTypeResult getArgType(ASTContext &Ctx, bool IsObjCLiteral) const;
|
||||
|
||||
const OptionalFlag &hasThousandsGrouping() const {
|
||||
return HasThousandsGrouping;
|
||||
|
|
|
@ -241,7 +241,8 @@ bool clang::analyze_format_string::ParsePrintfString(FormatStringHandler &H,
|
|||
// Methods on PrintfSpecifier.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
ArgTypeResult PrintfSpecifier::getArgType(ASTContext &Ctx) const {
|
||||
ArgTypeResult PrintfSpecifier::getArgType(ASTContext &Ctx,
|
||||
bool IsObjCLiteral) const {
|
||||
const PrintfConversionSpecifier &CS = getConversionSpecifier();
|
||||
|
||||
if (!CS.consumesDataArgument())
|
||||
|
@ -309,13 +310,19 @@ ArgTypeResult PrintfSpecifier::getArgType(ASTContext &Ctx) const {
|
|||
|
||||
switch (CS.getKind()) {
|
||||
case ConversionSpecifier::sArg:
|
||||
if (LM.getKind() == LengthModifier::AsWideChar)
|
||||
if (LM.getKind() == LengthModifier::AsWideChar) {
|
||||
if (IsObjCLiteral)
|
||||
return Ctx.getPointerType(Ctx.UnsignedShortTy.withConst());
|
||||
return ArgTypeResult(ArgTypeResult::WCStrTy, "wchar_t *");
|
||||
}
|
||||
return ArgTypeResult::CStrTy;
|
||||
case ConversionSpecifier::SArg:
|
||||
// FIXME: This appears to be Mac OS X specific.
|
||||
if (IsObjCLiteral)
|
||||
return Ctx.getPointerType(Ctx.UnsignedShortTy.withConst());
|
||||
return ArgTypeResult(ArgTypeResult::WCStrTy, "wchar_t *");
|
||||
case ConversionSpecifier::CArg:
|
||||
if (IsObjCLiteral)
|
||||
return Ctx.UnsignedShortTy;
|
||||
return ArgTypeResult(Ctx.WCharTy, "wchar_t");
|
||||
case ConversionSpecifier::pArg:
|
||||
return ArgTypeResult::CPointerTy;
|
||||
|
|
|
@ -2162,7 +2162,8 @@ CheckPrintfHandler::HandlePrintfSpecifier(const analyze_printf::PrintfSpecifier
|
|||
// Now type check the data expression that matches the
|
||||
// format specifier.
|
||||
const Expr *Ex = getDataArg(argIndex);
|
||||
const analyze_printf::ArgTypeResult &ATR = FS.getArgType(S.Context);
|
||||
const analyze_printf::ArgTypeResult &ATR = FS.getArgType(S.Context,
|
||||
IsObjCLiteral);
|
||||
if (ATR.isValid() && !ATR.matchesType(S.Context, Ex->getType())) {
|
||||
// Check if we didn't match because of an implicit cast from a 'char'
|
||||
// or 'short' to an 'int'. This is done because printf is a varargs
|
||||
|
|
|
@ -115,3 +115,35 @@ extern NSString *GetLocalizedString(NSString *str);
|
|||
void check_NSLocalizedString() {
|
||||
[Foo fooWithFormat:NSLocalizedString(@"format"), @"arg"]; // no-warning
|
||||
}
|
||||
|
||||
typedef __WCHAR_TYPE__ wchar_t;
|
||||
|
||||
|
||||
// Test that %S, %C, %ls check for 16 bit types in ObjC strings, as described at
|
||||
// http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/Strings/Articles/formatSpecifiers.html#//apple_ref/doc/uid/TP40004265
|
||||
|
||||
void test_percent_S() {
|
||||
const unsigned short data[] = { 'a', 'b', 0 };
|
||||
const unsigned short* ptr = data;
|
||||
NSLog(@"%S", ptr); // no-warning
|
||||
|
||||
const wchar_t* wchar_ptr = L"ab";
|
||||
NSLog(@"%S", wchar_ptr); // expected-warning{{format specifies type 'const unsigned short *' but the argument has type 'const wchar_t *'}}
|
||||
}
|
||||
|
||||
void test_percent_ls() {
|
||||
const unsigned short data[] = { 'a', 'b', 0 };
|
||||
const unsigned short* ptr = data;
|
||||
NSLog(@"%ls", ptr); // no-warning
|
||||
|
||||
const wchar_t* wchar_ptr = L"ab";
|
||||
NSLog(@"%ls", wchar_ptr); // expected-warning{{format specifies type 'const unsigned short *' but the argument has type 'const wchar_t *'}}
|
||||
}
|
||||
|
||||
void test_percent_C() {
|
||||
const unsigned short data = 'a';
|
||||
NSLog(@"%C", data); // no-warning
|
||||
|
||||
const wchar_t wchar_data = L'a';
|
||||
NSLog(@"%C", wchar_data); // expected-warning{{format specifies type 'unsigned short' but the argument has type 'wchar_t'}}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue