forked from OSchip/llvm-project
Special case '%C' handling in ObjC format strings to handle integer literals that can represent unicode characters
Fixes <rdar://problem/13991617>. llvm-svn: 192673
This commit is contained in:
parent
ef9e993eaa
commit
da2f405b09
|
@ -3115,7 +3115,15 @@ CheckPrintfHandler::checkFormatExpr(const analyze_printf::PrintfSpecifier &FS,
|
|||
// 'unichar' is defined as a typedef of unsigned short, but we should
|
||||
// prefer using the typedef if it is visible.
|
||||
IntendedTy = S.Context.UnsignedShortTy;
|
||||
|
||||
|
||||
// While we are here, check if the value is an IntegerLiteral that happens
|
||||
// to be within the valid range.
|
||||
if (const IntegerLiteral *IL = dyn_cast<IntegerLiteral>(E)) {
|
||||
const llvm::APInt &V = IL->getValue();
|
||||
if (V.getActiveBits() <= S.Context.getTypeSize(IntendedTy))
|
||||
return true;
|
||||
}
|
||||
|
||||
LookupResult Result(S, &S.Context.Idents.get("unichar"), E->getLocStart(),
|
||||
Sema::LookupOrdinaryName);
|
||||
if (S.LookupName(Result, S.getCurScope())) {
|
||||
|
|
|
@ -186,26 +186,26 @@ void test_percent_C() {
|
|||
const unsigned short data = 'a';
|
||||
NSLog(@"%C", data); // no-warning
|
||||
|
||||
NSLog(@"%C", 0x2603); // expected-warning{{format specifies type 'unichar' (aka 'unsigned short') but the argument has type 'int'}}
|
||||
NSLog(@"%C", 0x260300); // expected-warning{{format specifies type 'unichar' (aka 'unsigned short') but the argument has type 'int'}}
|
||||
// CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:13}:"%d"
|
||||
// CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:16-[[@LINE-2]]:16}:"(unsigned short)"
|
||||
|
||||
typedef unsigned short unichar;
|
||||
|
||||
NSLog(@"%C", 0x2603); // expected-warning{{format specifies type 'unichar' (aka 'unsigned short') but the argument has type 'int'}}
|
||||
NSLog(@"%C", 0x260300); // expected-warning{{format specifies type 'unichar' (aka 'unsigned short') but the argument has type 'int'}}
|
||||
// CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:13}:"%d"
|
||||
// CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:16-[[@LINE-2]]:16}:"(unichar)"
|
||||
|
||||
NSLog(@"%C", data ? 0x2F : 0x2603); // expected-warning{{format specifies type 'unichar' (aka 'unsigned short') but the argument has type 'int'}}
|
||||
NSLog(@"%C", data ? 0x2F0000 : 0x260300); // expected-warning{{format specifies type 'unichar' (aka 'unsigned short') but the argument has type 'int'}}
|
||||
// CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:13}:"%d"
|
||||
// CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:16-[[@LINE-2]]:16}:"(unichar)("
|
||||
// CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:36-[[@LINE-3]]:36}:")"
|
||||
// CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:42-[[@LINE-3]]:42}:")"
|
||||
|
||||
NSLog(@"%C", 0.0); // expected-warning{{format specifies type 'unichar' (aka 'unsigned short') but the argument has type 'double'}}
|
||||
// CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:13}:"%f"
|
||||
// CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-2]]:16-[[@LINE-2]]:16}:"(unichar)"
|
||||
|
||||
NSLog(@"%C", (char)0x2603); // expected-warning{{format specifies type 'unichar' (aka 'unsigned short') but the argument has type 'char'}}
|
||||
NSLog(@"%C", (char)0x260300); // expected-warning{{format specifies type 'unichar' (aka 'unsigned short') but the argument has type 'char'}}
|
||||
// CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:13}:"%c"
|
||||
// CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-2]]:16-[[@LINE-2]]:22}:"(unichar)"
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ void test_percent_C() {
|
|||
NSLog(@"%C", wchar_data); // expected-warning{{format specifies type 'unichar' (aka 'unsigned short') but the argument has type 'wchar_t'}}
|
||||
// CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:16-[[@LINE-1]]:16}:"(unsigned short)"
|
||||
|
||||
NSLog(@"%C", 0x2603); // expected-warning{{format specifies type 'unichar' (aka 'unsigned short') but the argument has type 'int'}}
|
||||
NSLog(@"%C", 0x260300); // expected-warning{{format specifies type 'unichar' (aka 'unsigned short') but the argument has type 'int'}}
|
||||
// CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:13}:"%d"
|
||||
// CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:16-[[@LINE-2]]:16}:"(unsigned short)"
|
||||
|
||||
|
@ -20,7 +20,7 @@ void test_percent_C() {
|
|||
NSLog(@"%C", wchar_data); // expected-warning{{format specifies type 'unichar' (aka 'unsigned short') but the argument has type 'wchar_t'}}
|
||||
// CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:16-[[@LINE-1]]:16}:"(unichar)"
|
||||
|
||||
NSLog(@"%C", 0x2603); // expected-warning{{format specifies type 'unichar' (aka 'unsigned short') but the argument has type 'int'}}
|
||||
NSLog(@"%C", 0x260300); // expected-warning{{format specifies type 'unichar' (aka 'unsigned short') but the argument has type 'int'}}
|
||||
// CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:13}:"%d"
|
||||
// CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:16-[[@LINE-2]]:16}:"(unichar)"
|
||||
|
||||
|
|
|
@ -243,3 +243,8 @@ void testTypeOf(NSInteger dW, NSInteger dH) {
|
|||
NSLog(@"dW %d dH %d",({ __typeof__(dW) __a = (dW); __a < 0 ? -__a : __a; }),({ __typeof__(dH) __a = (dH); __a < 0 ? -__a : __a; })); // expected-warning 2 {{values of type 'NSInteger' should not be used as format arguments; add an explicit cast to 'long' instead}}
|
||||
}
|
||||
|
||||
void testUnicode() {
|
||||
NSLog(@"%C", 0x2022); // no-warning
|
||||
NSLog(@"%C", 0x202200); // expected-warning{{format specifies type 'unichar' (aka 'unsigned short') but the argument has type 'int'}}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue