Author: nico Date: Mon Jan 30 19:43:25 2012 New Revision: 149325 URL: http://llvm.org/viewvc/llvm-project?rev=149325&view=rev Log: 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 Modified: cfe/trunk/include/clang/Analysis/Analyses/FormatString.h cfe/trunk/lib/Analysis/PrintfFormatString.cpp cfe/trunk/lib/Sema/SemaChecking.cpp cfe/trunk/test/SemaObjC/format-strings-objc.m Modified: cfe/trunk/include/clang/Analysis/Analyses/FormatString.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/Analyses/FormatString.h?rev=149325&r1=149324&r2=149325&view=diff ============================================================================== --- cfe/trunk/include/clang/Analysis/Analyses/FormatString.h (original) +++ cfe/trunk/include/clang/Analysis/Analyses/FormatString.h Mon Jan 30 19:43:25 2012 @@ -455,7 +455,7 @@ /// 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; Modified: cfe/trunk/lib/Analysis/PrintfFormatString.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/PrintfFormatString.cpp?rev=149325&r1=149324&r2=149325&view=diff ============================================================================== --- cfe/trunk/lib/Analysis/PrintfFormatString.cpp (original) +++ cfe/trunk/lib/Analysis/PrintfFormatString.cpp Mon Jan 30 19:43:25 2012 @@ -241,7 +241,8 @@ // 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 @@ 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; Modified: cfe/trunk/lib/Sema/SemaChecking.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaChecking.cpp?rev=149325&r1=149324&r2=149325&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaChecking.cpp (original) +++ cfe/trunk/lib/Sema/SemaChecking.cpp Mon Jan 30 19:43:25 2012 @@ -2162,7 +2162,8 @@ // 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 Modified: cfe/trunk/test/SemaObjC/format-strings-objc.m URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/format-strings-objc.m?rev=149325&r1=149324&r2=149325&view=diff ============================================================================== --- cfe/trunk/test/SemaObjC/format-strings-objc.m (original) +++ cfe/trunk/test/SemaObjC/format-strings-objc.m Mon Jan 30 19:43:25 2012 @@ -115,3 +115,35 @@ 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'}} +} _______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
