1// RUN: %clang_cc1 -fsyntax-only -verify -Wno-array-bounds %s -fpascal-strings 2// RUN: %clang_cc1 -fdiagnostics-parseable-fixits -x c++ %s 2>&1 -Wno-array-bounds -fpascal-strings | FileCheck %s 3 4void consume(const char* c) {} 5void consume(const unsigned char* c) {} 6void consume(const wchar_t* c) {} 7void consumeChar(char c) {} 8 9enum MyEnum { 10 kMySmallEnum = 1, 11 kMyEnum = 5 12}; 13 14enum OperatorOverloadEnum { 15 kMyOperatorOverloadedEnum = 5 16}; 17 18const char* operator+(const char* c, OperatorOverloadEnum e) { 19 return "yo"; 20} 21 22const char* operator+(OperatorOverloadEnum e, const char* c) { 23 return "yo"; 24} 25 26void f(int index) { 27 // Should warn. 28 // CHECK: fix-it:"{{.*}}":{31:11-31:11}:"&" 29 // CHECK: fix-it:"{{.*}}":{31:17-31:18}:"[" 30 // CHECK: fix-it:"{{.*}}":{31:20-31:20}:"]" 31 consume("foo" + 5); // expected-warning {{adding 'int' to a string does not append to the string}} expected-note {{use array indexing to silence this warning}} 32 consume("foo" + index); // expected-warning {{adding 'int' to a string does not append to the string}} expected-note {{use array indexing to silence this warning}} 33 consume("foo" + kMyEnum); // expected-warning {{adding 'MyEnum' to a string does not append to the string}} expected-note {{use array indexing to silence this warning}} 34 35 consume(5 + "foo"); // expected-warning {{adding 'int' to a string does not append to the string}} expected-note {{use array indexing to silence this warning}} 36 consume(index + "foo"); // expected-warning {{adding 'int' to a string does not append to the string}} expected-note {{use array indexing to silence this warning}} 37 consume(kMyEnum + "foo"); // expected-warning {{adding 'MyEnum' to a string does not append to the string}} expected-note {{use array indexing to silence this warning}} 38 39 // FIXME: suggest replacing with "foo"[5] 40 consumeChar(*("foo" + 5)); // expected-warning {{adding 'int' to a string does not append to the string}} expected-note {{use array indexing to silence this warning}} 41 consumeChar(*(5 + "foo")); // expected-warning {{adding 'int' to a string does not append to the string}} expected-note {{use array indexing to silence this warning}} 42 43 consume(L"foo" + 5); // expected-warning {{adding 'int' to a string does not append to the string}} expected-note {{use array indexing to silence this warning}} 44 45 // Should not warn. 46 consume(&("foo"[3])); 47 consume(&("foo"[index])); 48 consume(&("foo"[kMyEnum])); 49 consume("foo" + kMySmallEnum); 50 consume(kMySmallEnum + "foo"); 51 52 consume(L"foo" + 2); 53 54 consume("foo" + 3); // Points at the \0 55 consume("foo" + 4); // Points 1 past the \0, which is legal too. 56 consume("\pfoo" + 4); // Pascal strings don't have a trailing \0, but they 57 // have a leading length byte, so this is fine too. 58 59 consume("foo" + kMyOperatorOverloadedEnum); 60 consume(kMyOperatorOverloadedEnum + "foo"); 61 62 #define A "foo" 63 #define B "bar" 64 consume(A B + sizeof(A) - 1); 65} 66 67