diff options
Diffstat (limited to 'test/FixIt')
-rw-r--r-- | test/FixIt/auto-isa-fixit.m | 66 | ||||
-rw-r--r-- | test/FixIt/bridge-cast-in-arc.mm | 19 | ||||
-rw-r--r-- | test/FixIt/bridge-in-non-arc.m | 12 | ||||
-rw-r--r-- | test/FixIt/fixit-c90.c | 2 | ||||
-rw-r--r-- | test/FixIt/fixit-cxx0x.cpp | 14 | ||||
-rw-r--r-- | test/FixIt/fixit-cxx11-attributes.cpp | 51 | ||||
-rw-r--r-- | test/FixIt/fixit-errors-1.c | 1 | ||||
-rw-r--r-- | test/FixIt/fixit-errors.c | 6 | ||||
-rw-r--r-- | test/FixIt/fixit-newline-style.c | 11 | ||||
-rw-r--r-- | test/FixIt/fixit-nsstring-compare.m | 22 | ||||
-rw-r--r-- | test/FixIt/fixit-objc.m | 2 | ||||
-rw-r--r-- | test/FixIt/fixit-unicode.c | 13 | ||||
-rw-r--r-- | test/FixIt/fixit.cpp | 8 | ||||
-rw-r--r-- | test/FixIt/format-darwin.m | 116 | ||||
-rw-r--r-- | test/FixIt/format.m | 135 | ||||
-rw-r--r-- | test/FixIt/format.mm | 30 | ||||
-rw-r--r-- | test/FixIt/typo.c | 10 |
17 files changed, 458 insertions, 60 deletions
diff --git a/test/FixIt/auto-isa-fixit.m b/test/FixIt/auto-isa-fixit.m new file mode 100644 index 0000000..3f22c18 --- /dev/null +++ b/test/FixIt/auto-isa-fixit.m @@ -0,0 +1,66 @@ +// RUN: cp %s %t +// RUN: %clang_cc1 -x objective-c -fixit %t +// RUN: %clang_cc1 -x objective-c -Werror %t +// rdar://13503456 + +void object_setClass(id, id); +Class object_getClass(id); + +id rhs(); + +Class pr6302(id x123) { + x123->isa = 0; + x123->isa = rhs(); + x123->isa = (id)(x123->isa); + x123->isa = (id)x123->isa; + x123->isa = (x123->isa); + x123->isa = (id)(x123->isa); + return x123->isa; +} + + +@interface BaseClass { +@public + Class isa; // expected-note 3 {{instance variable is declared here}} +} +@end + +@interface OtherClass { +@public + id firstIvar; + Class isa; // note, not first ivar; +} +@end + +@interface Subclass : BaseClass @end + +@interface SiblingClass : BaseClass @end + +@interface Root @end + +@interface hasIsa : Root { +@public + Class isa; // note, isa is not in root class +} +@end + +@implementation Subclass +-(void)method { + hasIsa *u; + id v; + BaseClass *w; + Subclass *x; + SiblingClass *y; + OtherClass *z; + (void)v->isa; + (void)w->isa; + (void)x->isa; + (void)y->isa; + (void)z->isa; + (void)u->isa; + y->isa = 0; + y->isa = w->isa; + x->isa = rhs(); +} +@end + diff --git a/test/FixIt/bridge-cast-in-arc.mm b/test/FixIt/bridge-cast-in-arc.mm new file mode 100644 index 0000000..5cd482f --- /dev/null +++ b/test/FixIt/bridge-cast-in-arc.mm @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fdiagnostics-parseable-fixits -x objective-c++ -fobjc-arc %s 2>&1 | FileCheck %s +// rdar://12788838 + +id obj; + +void Test1() { + void *foo = reinterpret_cast<void *>(obj); +} +// CHECK: {7:15-7:39}:"(__bridge void *)" +// CHECK: {7:15-7:39}:"(__bridge_retained void *)" + +typedef const void * CFTypeRef; +extern "C" CFTypeRef CFBridgingRetain(id X); + +void Test2() { + void *foo = reinterpret_cast<void *>(obj); +} +// CHECK: {16:15-16:39}:"(__bridge void *)" +// CHECK: {16:15-16:39}:"CFBridgingRetain" diff --git a/test/FixIt/bridge-in-non-arc.m b/test/FixIt/bridge-in-non-arc.m new file mode 100644 index 0000000..b4d2677 --- /dev/null +++ b/test/FixIt/bridge-in-non-arc.m @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s + +@interface I +@end + +void foo(void *p) { + I *i = (__bridge_transfer I*)p; + I *i2 = (__bridge_transfer/*cake*/I*)p; +} + +// CHECK: {7:11-7:29}:"" +// CHECK: {8:12-8:29}:"" diff --git a/test/FixIt/fixit-c90.c b/test/FixIt/fixit-c90.c index 0bc1fad..5e9d5a1 100644 --- a/test/FixIt/fixit-c90.c +++ b/test/FixIt/fixit-c90.c @@ -2,7 +2,7 @@ RUN: %clang_cc1 -std=c90 -pedantic -fixit %t RUN: %clang_cc1 -pedantic -x c -std=c90 -Werror %t */ -/* XPASS: * +/* This test passes because clang merely warns for this syntax error even with -pedantic -Werror -std=c90. */ diff --git a/test/FixIt/fixit-cxx0x.cpp b/test/FixIt/fixit-cxx0x.cpp index a173ce4..1f6275f 100644 --- a/test/FixIt/fixit-cxx0x.cpp +++ b/test/FixIt/fixit-cxx0x.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -verify -std=c++11 %s +// RUN: %clang_cc1 -verify -std=c++11 -Wno-anonymous-pack-parens %s // RUN: cp %s %t // RUN: not %clang_cc1 -x c++ -std=c++11 -fixit %t // RUN: %clang_cc1 -Wall -pedantic -x c++ -std=c++11 %t @@ -120,3 +120,15 @@ namespace MissingSemi { struct d // expected-error {{expected ';' after struct}} } } + +namespace NonStaticConstexpr { + struct foo { + constexpr int i; // expected-error {{non-static data member cannot be constexpr; did you intend to make it const?}} + constexpr int j = 7; // expected-error {{non-static data member cannot be constexpr; did you intend to make it static?}} + foo() : i(3) { + } + static int get_j() { + return j; + } + }; +} diff --git a/test/FixIt/fixit-cxx11-attributes.cpp b/test/FixIt/fixit-cxx11-attributes.cpp new file mode 100644 index 0000000..f28bdfc --- /dev/null +++ b/test/FixIt/fixit-cxx11-attributes.cpp @@ -0,0 +1,51 @@ +// RUN: %clang_cc1 -verify -std=c++11 %s +// RUN: cp %s %t +// RUN: not %clang_cc1 -x c++ -std=c++11 -fixit %t +// RUN: %clang_cc1 -Wall -pedantic -x c++ -std=c++11 %t +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s + +namespace ClassSpecifier { + class [[]] [[]] + attr_after_class_name_decl [[]] [[]]; // expected-error {{an attribute list cannot appear here}} + // CHECK: fix-it:{{.*}}:{9:5-9:5} + // CHECK: fix-it:{{.*}}:{9:32-9:41} + + class [[]] [[]] + attr_after_class_name_definition [[]] [[]] [[]]{}; // expected-error {{an attribute list cannot appear here}} + // CHECK: fix-it:{{.*}}:{14:4-14:4} + // CHECK: fix-it:{{.*}}:{14:37-14:51} + + class base {}; + class [[]] [[]] final_class + alignas(float) [[]] final // expected-error {{an attribute list cannot appear here}} + alignas(float) [[]] [[]] alignas(float): base{}; // expected-error {{an attribute list cannot appear here}} + // CHECK: fix-it:{{.*}}:{19:19-19:19} + // CHECK: fix-it:{{.*}}:{20:5-20:25} + // CHECK: fix-it:{{.*}}:{19:19-19:19} + // CHECK: fix-it:{{.*}}:{21:5-21:44} + + class [[]] [[]] final_class_another + [[]] [[]] alignas(16) final // expected-error {{an attribute list cannot appear here}} + [[]] [[]] alignas(16) [[]]{}; // expected-error {{an attribute list cannot appear here}} + // CHECK: fix-it:{{.*}}:{27:19-27:19} + // CHECK: fix-it:{{.*}}:{28:5-28:27} + // CHECK: fix-it:{{.*}}:{27:19-27:19} + // CHECK: fix-it:{{.*}}:{29:5-29:31} +} + +namespace BaseSpecifier { + struct base1 {}; + struct base2 {}; + class with_base_spec : public [[a]] // expected-error {{an attribute list cannot appear here}} expected-warning {{unknown}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:26-[[@LINE-1]]:26}:"[{{\[}}a]]" + // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:33-[[@LINE-2]]:39}:"" + virtual [[b]] base1, // expected-error {{an attribute list cannot appear here}} expected-warning {{unknown}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:26-[[@LINE-4]]:26}:"[{{\[}}b]]" + // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:34-[[@LINE-2]]:40}:"" + virtual [[c]] // expected-error {{an attribute list cannot appear here}} expected-warning {{unknown}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:26-[[@LINE-1]]:26}:"[{{\[}}c]]" + // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:34-[[@LINE-2]]:40}:"" + public [[d]] base2 {}; // expected-error {{an attribute list cannot appear here}} expected-warning {{unknown}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:26-[[@LINE-4]]:26}:"[{{\[}}d]]" + // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:33-[[@LINE-2]]:39}:"" +} diff --git a/test/FixIt/fixit-errors-1.c b/test/FixIt/fixit-errors-1.c index 96f27eb..b034b19 100644 --- a/test/FixIt/fixit-errors-1.c +++ b/test/FixIt/fixit-errors-1.c @@ -1,7 +1,6 @@ // RUN: cp %s %t // RUN: %clang_cc1 -pedantic -fixit %t // RUN: echo %clang_cc1 -pedantic -Werror -x c %t -/* XPASS: * */ /* This is a test of the various code modification hints that are provided as part of warning or extension diagnostics. All of the diff --git a/test/FixIt/fixit-errors.c b/test/FixIt/fixit-errors.c index 356e862..c425fc8 100644 --- a/test/FixIt/fixit-errors.c +++ b/test/FixIt/fixit-errors.c @@ -1,7 +1,7 @@ +// RUN: %clang_cc1 -fsyntax-only -pedantic -verify %s // RUN: cp %s %t -// RUN: %clang_cc1 -pedantic -verify -fixit -x c %t +// RUN: not %clang_cc1 -pedantic -fixit -x c %t // RUN: %clang_cc1 -pedantic -Werror -x c %t -// XFAIL: * /* This is a test of the various code modification hints that are provided as part of warning or extension diagnostics. All of the @@ -19,5 +19,5 @@ struct Point { struct Point *get_origin(); void test_point() { - (void)get_origin->x; + (void)get_origin->x; // expected-error {{base of member reference is a function; perhaps you meant to call it with no arguments?}} } diff --git a/test/FixIt/fixit-newline-style.c b/test/FixIt/fixit-newline-style.c new file mode 100644 index 0000000..c43eb37 --- /dev/null +++ b/test/FixIt/fixit-newline-style.c @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -pedantic -Wunused-label -x c %s 2>&1 | FileCheck %s -strict-whitespace
+
+// This file intentionally uses a CRLF newline style
+// <rdar://problem/12639047>
+// CHECK: warning: unused label 'ddd'
+// CHECK-NEXT: {{^ ddd:}}
+// CHECK-NEXT: {{^ \^~~~$}}
+void f() {
+ ddd:
+ ;
+}
diff --git a/test/FixIt/fixit-nsstring-compare.m b/test/FixIt/fixit-nsstring-compare.m new file mode 100644 index 0000000..6f0877c --- /dev/null +++ b/test/FixIt/fixit-nsstring-compare.m @@ -0,0 +1,22 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fdiagnostics-parseable-fixits -x objective-c %s 2>&1 | FileCheck %s +// rdar://12716301 + +typedef unsigned char BOOL; + +@protocol NSObject +- (BOOL)isEqual:(id)object; +@end + +@interface NSString<NSObject> +@end + +int main() { + NSString *stringA = @"stringA"; + + BOOL comparison = stringA==@"stringB"; + +} + +// CHECK: {16:21-16:21}:"[" +// CHECK: {16:28-16:30}:" isEqual:" +// CHECK: {16:40-16:40}:"]" diff --git a/test/FixIt/fixit-objc.m b/test/FixIt/fixit-objc.m index 77099fc..ea57fe6 100644 --- a/test/FixIt/fixit-objc.m +++ b/test/FixIt/fixit-objc.m @@ -11,7 +11,7 @@ @protocol X; void foo() { - <X> *P; // expected-warning{{protocol qualifiers without 'id' is archaic}} + <X> *P; // expected-warning{{protocol has no object type specified; defaults to qualified 'id'}} } @class A; diff --git a/test/FixIt/fixit-unicode.c b/test/FixIt/fixit-unicode.c index 2af5e08..9c0242e 100644 --- a/test/FixIt/fixit-unicode.c +++ b/test/FixIt/fixit-unicode.c @@ -8,13 +8,16 @@ struct Foo { // PR13312 void test1() { struct Foo foo; - (&foo)☃>bar = 42; + foo.bar = 42☃ +// CHECK: error: non-ASCII characters are not allowed outside of literals and identifiers +// CHECK: {{^ \^}} // CHECK: error: expected ';' after expression // Make sure we emit the fixit right in front of the snowman. -// CHECK: {{^ \^}} -// CHECK: {{^ ;}} +// CHECK: {{^ \^}} +// CHECK: {{^ ;}} -// CHECK-MACHINE: fix-it:"{{.*}}fixit-unicode.c":{11:9-11:9}:";" +// CHECK-MACHINE: fix-it:"{{.*}}fixit-unicode.c":{[[@LINE-8]]:15-[[@LINE-8]]:18}:"" +// CHECK-MACHINE: fix-it:"{{.*}}fixit-unicode.c":{[[@LINE-9]]:15-[[@LINE-9]]:15}:";" } @@ -29,5 +32,5 @@ void test2() { // because different systems will render the delta differently (either as a // character, or as <U+2206>.) The fixit should line up with the %d regardless. -// CHECK-MACHINE: fix-it:"{{.*}}fixit-unicode.c":{23:16-23:18}:"%ld" +// CHECK-MACHINE: fix-it:"{{.*}}fixit-unicode.c":{[[@LINE-9]]:16-[[@LINE-9]]:18}:"%ld" } diff --git a/test/FixIt/fixit.cpp b/test/FixIt/fixit.cpp index 253abd0..fca596b 100644 --- a/test/FixIt/fixit.cpp +++ b/test/FixIt/fixit.cpp @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -pedantic -Wall -Wno-comment -verify -fcxx-exceptions -x c++ %s +// RUN: %clang_cc1 -fsyntax-only -fdiagnostics-parseable-fixits -x c++ %s 2>&1 | FileCheck %s // RUN: cp %s %t // RUN: not %clang_cc1 -pedantic -Wall -Wno-comment -fcxx-exceptions -fixit -x c++ %t // RUN: %clang_cc1 -fsyntax-only -pedantic -Wall -Werror -Wno-comment -fcxx-exceptions -x c++ %t @@ -299,3 +300,10 @@ class foo { } int i(); }; + +namespace dtor_fixit { + class foo { + ~bar() { } // expected-error {{expected the class name after '~' to name a destructor}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:6-[[@LINE-1]]:9}:"foo" + }; +} diff --git a/test/FixIt/format-darwin.m b/test/FixIt/format-darwin.m index 1bfe272..f520564 100644 --- a/test/FixIt/format-darwin.m +++ b/test/FixIt/format-darwin.m @@ -23,6 +23,8 @@ typedef long SInt32; typedef unsigned long UInt32; #endif +typedef SInt32 OSStatus; + NSInteger getNSInteger(); NSUInteger getNSUInteger(); SInt32 getSInt32(); @@ -34,17 +36,17 @@ void testCorrectionInAllCases() { printf("%s", getSInt32()); // expected-warning{{values of type 'SInt32' should not be used as format arguments; add an explicit cast to 'int' instead}} printf("%s", getUInt32()); // expected-warning{{values of type 'UInt32' should not be used as format arguments; add an explicit cast to 'unsigned int' instead}} - // CHECK: fix-it:"{{.*}}":{32:11-32:13}:"%ld" - // CHECK: fix-it:"{{.*}}":{32:16-32:16}:"(long)" + // CHECK: fix-it:"{{.*}}":{[[@LINE-5]]:11-[[@LINE-5]]:13}:"%ld" + // CHECK: fix-it:"{{.*}}":{[[@LINE-6]]:16-[[@LINE-6]]:16}:"(long)" - // CHECK: fix-it:"{{.*}}":{33:11-33:13}:"%lu" - // CHECK: fix-it:"{{.*}}":{33:16-33:16}:"(unsigned long)" + // CHECK: fix-it:"{{.*}}":{[[@LINE-7]]:11-[[@LINE-7]]:13}:"%lu" + // CHECK: fix-it:"{{.*}}":{[[@LINE-8]]:16-[[@LINE-8]]:16}:"(unsigned long)" - // CHECK: fix-it:"{{.*}}":{34:11-34:13}:"%d" - // CHECK: fix-it:"{{.*}}":{34:16-34:16}:"(int)" + // CHECK: fix-it:"{{.*}}":{[[@LINE-9]]:11-[[@LINE-9]]:13}:"%d" + // CHECK: fix-it:"{{.*}}":{[[@LINE-10]]:16-[[@LINE-10]]:16}:"(int)" - // CHECK: fix-it:"{{.*}}":{35:11-35:13}:"%u" - // CHECK: fix-it:"{{.*}}":{35:16-35:16}:"(unsigned int)" + // CHECK: fix-it:"{{.*}}":{[[@LINE-11]]:11-[[@LINE-11]]:13}:"%u" + // CHECK: fix-it:"{{.*}}":{[[@LINE-12]]:16-[[@LINE-12]]:16}:"(unsigned int)" } @interface Foo { @@ -65,7 +67,7 @@ void testParens(Foo *obj, struct Bar *record) { NSInteger arr[4] = {0}; NSInteger i = 0; - // These cases match the cases in CheckPrintfHandler::checkFormatExpr. + // These cases match the relevant cases in CheckPrintfHandler::checkFormatExpr. printf("%s", arr[0]); // expected-warning{{values of type 'NSInteger' should not be used as format arguments; add an explicit cast to 'long' instead}} printf("%s", getNSInteger()); // expected-warning{{values of type 'NSInteger' should not be used as format arguments; add an explicit cast to 'long' instead}} printf("%s", i); // expected-warning{{values of type 'NSInteger' should not be used as format arguments; add an explicit cast to 'long' instead}} @@ -80,9 +82,9 @@ void testParens(Foo *obj, struct Bar *record) { printf("%s", i ? i : i); // expected-warning{{values of type 'NSInteger' should not be used as format arguments; add an explicit cast to 'long' instead}} - // CHECK: fix-it:"{{.*}}":{81:11-81:13}:"%ld" - // CHECK: fix-it:"{{.*}}":{81:16-81:16}:"(long)(" - // CHECK: fix-it:"{{.*}}":{81:25-81:25}:")" + // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:11-[[@LINE-2]]:13}:"%ld" + // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:16-[[@LINE-3]]:16}:"(long)(" + // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:25-[[@LINE-4]]:25}:")" } @@ -94,28 +96,38 @@ void testWarn() { printf("%ld", getSInt32()); // expected-warning{{values of type 'SInt32' should not be used as format arguments; add an explicit cast to 'int' instead}} printf("%lu", getUInt32()); // expected-warning{{values of type 'UInt32' should not be used as format arguments; add an explicit cast to 'unsigned int' instead}} - // CHECK-64: fix-it:"{{.*}}":{92:11-92:13}:"%ld" - // CHECK-64: fix-it:"{{.*}}":{92:16-92:16}:"(long)" + // CHECK-64: fix-it:"{{.*}}":{[[@LINE-5]]:11-[[@LINE-5]]:13}:"%ld" + // CHECK-64: fix-it:"{{.*}}":{[[@LINE-6]]:16-[[@LINE-6]]:16}:"(long)" - // CHECK-64: fix-it:"{{.*}}":{93:11-93:13}:"%lu" - // CHECK-64: fix-it:"{{.*}}":{93:16-93:16}:"(unsigned long)" + // CHECK-64: fix-it:"{{.*}}":{[[@LINE-7]]:11-[[@LINE-7]]:13}:"%lu" + // CHECK-64: fix-it:"{{.*}}":{[[@LINE-8]]:16-[[@LINE-8]]:16}:"(unsigned long)" - // CHECK-64: fix-it:"{{.*}}":{94:11-94:14}:"%d" - // CHECK-64: fix-it:"{{.*}}":{94:17-94:17}:"(int)" + // CHECK-64: fix-it:"{{.*}}":{[[@LINE-9]]:11-[[@LINE-9]]:14}:"%d" + // CHECK-64: fix-it:"{{.*}}":{[[@LINE-10]]:17-[[@LINE-10]]:17}:"(int)" - // CHECK-64: fix-it:"{{.*}}":{95:11-95:14}:"%u" - // CHECK-64: fix-it:"{{.*}}":{95:17-95:17}:"(unsigned int)" + // CHECK-64: fix-it:"{{.*}}":{[[@LINE-11]]:11-[[@LINE-11]]:14}:"%u" + // CHECK-64: fix-it:"{{.*}}":{[[@LINE-12]]:17-[[@LINE-12]]:17}:"(unsigned int)" } void testPreserveHex() { printf("%x", getNSInteger()); // expected-warning{{values of type 'NSInteger' should not be used as format arguments; add an explicit cast to 'long' instead}} printf("%x", getNSUInteger()); // expected-warning{{values of type 'NSUInteger' should not be used as format arguments; add an explicit cast to 'unsigned long' instead}} - // CHECK-64: fix-it:"{{.*}}":{111:11-111:13}:"%lx" - // CHECK-64: fix-it:"{{.*}}":{111:16-111:16}:"(long)" + // CHECK-64: fix-it:"{{.*}}":{[[@LINE-3]]:11-[[@LINE-3]]:13}:"%lx" + // CHECK-64: fix-it:"{{.*}}":{[[@LINE-4]]:16-[[@LINE-4]]:16}:"(long)" + + // CHECK-64: fix-it:"{{.*}}":{[[@LINE-5]]:11-[[@LINE-5]]:13}:"%lx" + // CHECK-64: fix-it:"{{.*}}":{[[@LINE-6]]:16-[[@LINE-6]]:16}:"(unsigned long)" +} + +void testSignedness(NSInteger i, NSUInteger u) { + printf("%d", u); // expected-warning{{values of type 'NSUInteger' should not be used as format arguments; add an explicit cast to 'unsigned long' instead}} + printf("%i", u); // expected-warning{{values of type 'NSUInteger' should not be used as format arguments; add an explicit cast to 'unsigned long' instead}} + printf("%u", i); // expected-warning{{values of type 'NSInteger' should not be used as format arguments; add an explicit cast to 'long' instead}} - // CHECK-64: fix-it:"{{.*}}":{112:11-112:13}:"%lx" - // CHECK-64: fix-it:"{{.*}}":{112:16-112:16}:"(unsigned long)" + // CHECK-64: fix-it:"{{.*}}":{[[@LINE-4]]:11-[[@LINE-4]]:13}:"%lu" + // CHECK-64: fix-it:"{{.*}}":{[[@LINE-4]]:11-[[@LINE-4]]:13}:"%lu" + // CHECK-64: fix-it:"{{.*}}":{[[@LINE-4]]:11-[[@LINE-4]]:13}:"%ld" } void testNoWarn() { @@ -133,22 +145,18 @@ void testWarn() { printf("%d", getSInt32()); // expected-warning{{values of type 'SInt32' should not be used as format arguments; add an explicit cast to 'int' instead}} printf("%u", getUInt32()); // expected-warning{{values of type 'UInt32' should not be used as format arguments; add an explicit cast to 'unsigned int' instead}} - // CHECK-32: fix-it:"{{.*}}":{131:17-131:17}:"(long)" - - // CHECK-32: fix-it:"{{.*}}":{132:17-132:17}:"(unsigned long)" - - // CHECK-32: fix-it:"{{.*}}":{133:16-133:16}:"(int)" - - // CHECK-32: fix-it:"{{.*}}":{134:16-134:16}:"(unsigned int)" + // CHECK-32: fix-it:"{{.*}}":{[[@LINE-5]]:17-[[@LINE-5]]:17}:"(long)" + // CHECK-32: fix-it:"{{.*}}":{[[@LINE-5]]:17-[[@LINE-5]]:17}:"(unsigned long)" + // CHECK-32: fix-it:"{{.*}}":{[[@LINE-5]]:16-[[@LINE-5]]:16}:"(int)" + // CHECK-32: fix-it:"{{.*}}":{[[@LINE-5]]:16-[[@LINE-5]]:16}:"(unsigned int)" } void testPreserveHex() { printf("%lx", getNSInteger()); // expected-warning{{values of type 'NSInteger' should not be used as format arguments; add an explicit cast to 'long' instead}} printf("%lx", getNSUInteger()); // expected-warning{{values of type 'NSUInteger' should not be used as format arguments; add an explicit cast to 'unsigned long' instead}} - // CHECK-32: fix-it:"{{.*}}":{146:17-146:17}:"(long)" - - // CHECK-32: fix-it:"{{.*}}":{147:17-147:17}:"(unsigned long)" + // CHECK-32: fix-it:"{{.*}}":{[[@LINE-3]]:17-[[@LINE-3]]:17}:"(long)" + // CHECK-32: fix-it:"{{.*}}":{[[@LINE-3]]:17-[[@LINE-3]]:17}:"(unsigned long)" } void testNoWarn() { @@ -158,6 +166,14 @@ void testNoWarn() { printf("%lu", getUInt32()); // no-warning } +void testSignedness(NSInteger i, NSUInteger u) { + // It is valid to use a specifier with the opposite signedness as long as + // the type is correct. + printf("%d", u); // no-warning + printf("%i", u); // no-warning + printf("%u", i); // no-warning +} + #endif @@ -167,17 +183,17 @@ void testCasts() { printf("%s", (SInt32)0); // expected-warning{{values of type 'SInt32' should not be used as format arguments; add an explicit cast to 'int' instead}} printf("%s", (UInt32)0); // expected-warning{{values of type 'UInt32' should not be used as format arguments; add an explicit cast to 'unsigned int' instead}} - // CHECK: fix-it:"{{.*}}":{165:11-165:13}:"%ld" - // CHECK: fix-it:"{{.*}}":{165:16-165:27}:"(long)" + // CHECK: fix-it:"{{.*}}":{[[@LINE-5]]:11-[[@LINE-5]]:13}:"%ld" + // CHECK: fix-it:"{{.*}}":{[[@LINE-6]]:16-[[@LINE-6]]:27}:"(long)" - // CHECK: fix-it:"{{.*}}":{166:11-166:13}:"%lu" - // CHECK: fix-it:"{{.*}}":{166:16-166:28}:"(unsigned long)" + // CHECK: fix-it:"{{.*}}":{[[@LINE-7]]:11-[[@LINE-7]]:13}:"%lu" + // CHECK: fix-it:"{{.*}}":{[[@LINE-8]]:16-[[@LINE-8]]:28}:"(unsigned long)" - // CHECK: fix-it:"{{.*}}":{167:11-167:13}:"%d" - // CHECK: fix-it:"{{.*}}":{167:16-167:24}:"(int)" + // CHECK: fix-it:"{{.*}}":{[[@LINE-9]]:11-[[@LINE-9]]:13}:"%d" + // CHECK: fix-it:"{{.*}}":{[[@LINE-10]]:16-[[@LINE-10]]:24}:"(int)" - // CHECK: fix-it:"{{.*}}":{168:11-168:13}:"%u" - // CHECK: fix-it:"{{.*}}":{168:16-168:24}:"(unsigned int)" + // CHECK: fix-it:"{{.*}}":{[[@LINE-11]]:11-[[@LINE-11]]:13}:"%u" + // CHECK: fix-it:"{{.*}}":{[[@LINE-12]]:16-[[@LINE-12]]:24}:"(unsigned int)" } void testCapitals() { @@ -185,14 +201,20 @@ void testCapitals() { printf("%U", 1); // expected-warning{{conversion specifier is not supported by ISO C}} expected-note {{did you mean to use 'u'?}} printf("%O", 1); // expected-warning{{conversion specifier is not supported by ISO C}} expected-note {{did you mean to use 'o'?}} - // CHECK: fix-it:"{{.*}}":{184:12-184:13}:"d" - // CHECK: fix-it:"{{.*}}":{185:12-185:13}:"u" - // CHECK: fix-it:"{{.*}}":{186:12-186:13}:"o" + // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:12-[[@LINE-4]]:13}:"d" + // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:12-[[@LINE-4]]:13}:"u" + // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:12-[[@LINE-4]]:13}:"o" printf("%lD", 1); // expected-warning{{conversion specifier is not supported by ISO C}} expected-note {{did you mean to use 'd'?}} expected-warning{{format specifies type 'long' but the argument has type 'int'}} // FIXME: offering two somewhat-conflicting fixits is less than ideal. - // CHECK: fix-it:"{{.*}}":{193:13-193:14}:"d" - // CHECK: fix-it:"{{.*}}":{193:11-193:14}:"%D" + // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:13-[[@LINE-3]]:14}:"d" + // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:11-[[@LINE-4]]:14}:"%D" } + +void testLayeredTypedefs(OSStatus i) { + printf("%s", i); // expected-warning {{values of type 'OSStatus' should not be used as format arguments}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:13}:"%d" +} + diff --git a/test/FixIt/format.m b/test/FixIt/format.m index c474701..919212b 100644 --- a/test/FixIt/format.m +++ b/test/FixIt/format.m @@ -93,3 +93,138 @@ void test_named_fixed_enum_correction(enum SomeSize x) { // CHECK: fix-it:"{{.*}}":{92:11-92:13}:"%zu" } + +typedef unsigned char uint8_t; +void test_char(char c, signed char s, unsigned char u, uint8_t n) { + NSLog(@"%s", c); // expected-warning{{format specifies type 'char *' but the argument has type 'char'}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:13}:"%c" + + NSLog(@"%lf", c); // expected-warning{{format specifies type 'double' but the argument has type 'char'}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:14}:"%c" + + NSLog(@"%@", c); // expected-warning{{format specifies type 'id' but the argument has type 'char'}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:13}:"%c" + + NSLog(@"%c", c); // no-warning + // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:13}:"%c" + + + NSLog(@"%s", s); // expected-warning{{format specifies type 'char *' but the argument has type 'signed char'}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:13}:"%c" + + NSLog(@"%lf", s); // expected-warning{{format specifies type 'double' but the argument has type 'signed char'}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:14}:"%c" + + NSLog(@"%@", s); // expected-warning{{format specifies type 'id' but the argument has type 'signed char'}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:13}:"%c" + + NSLog(@"%c", s); // no-warning + // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:13}:"%c" + + + NSLog(@"%s", u); // expected-warning{{format specifies type 'char *' but the argument has type 'unsigned char'}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:13}:"%c" + + NSLog(@"%lf", u); // expected-warning{{format specifies type 'double' but the argument has type 'unsigned char'}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:14}:"%c" + + NSLog(@"%@", u); // expected-warning{{format specifies type 'id' but the argument has type 'unsigned char'}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:13}:"%c" + + NSLog(@"%c", u); // no-warning + // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:13}:"%c" + + + NSLog(@"%s", n); // expected-warning{{format specifies type 'char *' but the argument has type 'uint8_t' (aka 'unsigned char')}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:13}:"%hhu" + + NSLog(@"%lf", n); // expected-warning{{format specifies type 'double' but the argument has type 'uint8_t' (aka 'unsigned char')}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:14}:"%hhu" + + NSLog(@"%@", n); // expected-warning{{format specifies type 'id' but the argument has type 'uint8_t' (aka 'unsigned char')}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:13}:"%hhu" + + NSLog(@"%c", n); // no-warning + // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:13}:"%hhu" + + + NSLog(@"%s", 'a'); // expected-warning{{format specifies type 'char *' but the argument has type 'char'}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:13}:"%c" + + NSLog(@"%lf", 'a'); // expected-warning{{format specifies type 'double' but the argument has type 'char'}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:14}:"%c" + + NSLog(@"%@", 'a'); // expected-warning{{format specifies type 'id' but the argument has type 'char'}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:13}:"%c" + + NSLog(@"%c", 'a'); // no-warning + // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:13}:"%c" + + + NSLog(@"%s", 'abcd'); // expected-warning{{format specifies type 'char *' but the argument has type 'int'}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:13}:"%d" + + NSLog(@"%lf", 'abcd'); // expected-warning{{format specifies type 'double' but the argument has type 'int'}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:14}:"%d" + + NSLog(@"%@", 'abcd'); // expected-warning{{format specifies type 'id' but the argument has type 'int'}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:13}:"%d" +} + +void multichar_constants_false_negative() { + // The value of a multi-character constant is implementation-defined, but + // almost certainly shouldn't be printed with %c. However, the current + // type-checker expects %c to correspond to an integer argument, because + // many C library functions like fgetc() actually return an int (using -1 + // as a sentinel). + NSLog(@"%c", 'abcd'); // missing-warning{{format specifies type 'char' but the argument has type 'int'}} + // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:13}:"%d" +} + + +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'}} + // 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'}} + // 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'}} + // 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}:")" + + 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'}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:13}:"%c" + // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-2]]:16-[[@LINE-2]]:22}:"(unichar)" + + NSLog(@"%C", 'a'); // 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)" +} + + +void testSignedness(long i, unsigned long u) { + printf("%d", u); // expected-warning{{format specifies type 'int' but the argument has type 'unsigned long'}} + printf("%i", u); // expected-warning{{format specifies type 'int' but the argument has type 'unsigned long'}} + printf("%u", i); // expected-warning{{format specifies type 'unsigned int' but the argument has type 'long'}} + + // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:11-[[@LINE-4]]:13}:"%lu" + // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:11-[[@LINE-4]]:13}:"%lu" + // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:11-[[@LINE-4]]:13}:"%ld" + + printf("%+d", u); // expected-warning{{format specifies type 'int' but the argument has type 'unsigned long'}} + + // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:11-[[@LINE-2]]:14}:"%+ld" +} diff --git a/test/FixIt/format.mm b/test/FixIt/format.mm new file mode 100644 index 0000000..64c6c47 --- /dev/null +++ b/test/FixIt/format.mm @@ -0,0 +1,30 @@ +// RUN: %clang_cc1 -fsyntax-only -fblocks -verify %s +// RUN: %clang_cc1 -fdiagnostics-parseable-fixits -fblocks %s 2>&1 | FileCheck %s + +extern "C" void NSLog(id, ...); + +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 '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'}} + // 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", 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'}} + // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:13}:"%d" + // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:16-[[@LINE-2]]:16}:"(unichar)" + + 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)" +} diff --git a/test/FixIt/typo.c b/test/FixIt/typo.c index 0bafd1b..8e380c9 100644 --- a/test/FixIt/typo.c +++ b/test/FixIt/typo.c @@ -1,8 +1,9 @@ // RUN: %clang_cc1 -fsyntax-only -verify %s +// RUN: %clang_cc1 -fsyntax-only -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s // RUN: cp %s %t // RUN: not %clang_cc1 -fsyntax-only -fixit -x c %t // RUN: %clang_cc1 -fsyntax-only -pedantic -Werror -x c %t -// RUN: grep "Rectangle" %t + struct Point { float x, y; }; @@ -21,17 +22,24 @@ struct Window { struct Window window = { .bunds. // expected-error{{field designator 'bunds' does not refer to any field in type 'struct Window'; did you mean 'bounds'?}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:4-[[@LINE-1]]:9}:"bounds" + topleft.x = 3.14, // expected-error{{field designator 'topleft' does not refer to any field in type 'struct Rectangle'; did you mean 'top_left'?}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:10}:"top_left" 2.71818, 5.0, 6.0, Red }; void test() { Rectangle r1; // expected-error{{must use 'struct' tag to refer to type 'Rectangle'}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:3}:"struct " r1.top_left.x = 0; typedef struct Rectangle Rectangle; // expected-note{{'Rectangle' declared here}} rectangle *r2 = &r1; // expected-error{{unknown type name 'rectangle'; did you mean 'Rectangle'?}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:12}:"Rectangle" + r2->top_left.y = 0; unsinged *ptr = 0; // expected-error{{use of undeclared identifier 'unsinged'; did you mean 'unsigned'?}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:3-[[@LINE-1]]:11}:"unsigned" *ptr = 17; } |