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 4 void consume(const char* c) {} 5 void consume(const unsigned char* c) {} 6 void consume(const wchar_t* c) {} 7 void consumeChar(char c) {} 8 9 enum MyEnum { 10 kMySmallEnum = 1, 11 kMyEnum = 5 12 }; 13 14 enum OperatorOverloadEnum { 15 kMyOperatorOverloadedEnum = 5 16 }; 17 18 const char* operator+(const char* c, OperatorOverloadEnum e) { 19 return "yo"; 20 } 21 22 const char* operator+(OperatorOverloadEnum e, const char* c) { 23 return "yo"; 24 } 25 26 void 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 template <typename T> 68 void PR21848() { 69 (void)(sizeof(T) + ""); // expected-warning {{to a string does not append to the string}} expected-note {{use array indexing to silence this warning}} 70 } 71 template void PR21848<int>(); // expected-note {{in instantiation of function template specialization 'PR21848<int>' requested here}} 72