[cfe-commits] r149325 - in /cfe/trunk: include/clang/Analysis/Analyses/FormatString.h lib/Analysis/PrintfFormatString.cpp lib/Sema/SemaChecking.cpp test/SemaObjC/format-strings-objc.m
Nico Weber
nicolasweber at gmx.de
Mon Jan 30 17:43:25 PST 2012
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'}}
+}
More information about the cfe-commits
mailing list