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