11cb2d742eb6635aeab6132ee5f0b5781d39487d7Nico Weber// RUN: %clang_cc1 -fsyntax-only -verify -Wno-array-bounds %s -fpascal-strings
2ff1e9cce64f9f4a94ebfbfd26aaca4c389382266Nico Weber// RUN: %clang_cc1 -fdiagnostics-parseable-fixits -x c++ %s 2>&1 -Wno-array-bounds -fpascal-strings | FileCheck %s
31cb2d742eb6635aeab6132ee5f0b5781d39487d7Nico Weber
41cb2d742eb6635aeab6132ee5f0b5781d39487d7Nico Webervoid consume(const char* c) {}
51cb2d742eb6635aeab6132ee5f0b5781d39487d7Nico Webervoid consume(const unsigned char* c) {}
61cb2d742eb6635aeab6132ee5f0b5781d39487d7Nico Webervoid consume(const wchar_t* c) {}
71cb2d742eb6635aeab6132ee5f0b5781d39487d7Nico Webervoid consumeChar(char c) {}
81cb2d742eb6635aeab6132ee5f0b5781d39487d7Nico Weber
91cb2d742eb6635aeab6132ee5f0b5781d39487d7Nico Weberenum MyEnum {
101cb2d742eb6635aeab6132ee5f0b5781d39487d7Nico Weber  kMySmallEnum = 1,
111cb2d742eb6635aeab6132ee5f0b5781d39487d7Nico Weber  kMyEnum = 5
121cb2d742eb6635aeab6132ee5f0b5781d39487d7Nico Weber};
131cb2d742eb6635aeab6132ee5f0b5781d39487d7Nico Weber
141cb2d742eb6635aeab6132ee5f0b5781d39487d7Nico Weberenum OperatorOverloadEnum {
151cb2d742eb6635aeab6132ee5f0b5781d39487d7Nico Weber  kMyOperatorOverloadedEnum = 5
161cb2d742eb6635aeab6132ee5f0b5781d39487d7Nico Weber};
171cb2d742eb6635aeab6132ee5f0b5781d39487d7Nico Weber
181cb2d742eb6635aeab6132ee5f0b5781d39487d7Nico Weberconst char* operator+(const char* c, OperatorOverloadEnum e) {
191cb2d742eb6635aeab6132ee5f0b5781d39487d7Nico Weber  return "yo";
201cb2d742eb6635aeab6132ee5f0b5781d39487d7Nico Weber}
211cb2d742eb6635aeab6132ee5f0b5781d39487d7Nico Weber
221cb2d742eb6635aeab6132ee5f0b5781d39487d7Nico Weberconst char* operator+(OperatorOverloadEnum e, const char* c) {
231cb2d742eb6635aeab6132ee5f0b5781d39487d7Nico Weber  return "yo";
241cb2d742eb6635aeab6132ee5f0b5781d39487d7Nico Weber}
251cb2d742eb6635aeab6132ee5f0b5781d39487d7Nico Weber
261cb2d742eb6635aeab6132ee5f0b5781d39487d7Nico Webervoid f(int index) {
271cb2d742eb6635aeab6132ee5f0b5781d39487d7Nico Weber  // Should warn.
28ff1e9cce64f9f4a94ebfbfd26aaca4c389382266Nico Weber  // CHECK: fix-it:"{{.*}}":{31:11-31:11}:"&"
29ff1e9cce64f9f4a94ebfbfd26aaca4c389382266Nico Weber  // CHECK: fix-it:"{{.*}}":{31:17-31:18}:"["
30ff1e9cce64f9f4a94ebfbfd26aaca4c389382266Nico Weber  // CHECK: fix-it:"{{.*}}":{31:20-31:20}:"]"
311cb2d742eb6635aeab6132ee5f0b5781d39487d7Nico Weber  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}}
321cb2d742eb6635aeab6132ee5f0b5781d39487d7Nico Weber  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}}
331cb2d742eb6635aeab6132ee5f0b5781d39487d7Nico Weber  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}}
341cb2d742eb6635aeab6132ee5f0b5781d39487d7Nico Weber
351cb2d742eb6635aeab6132ee5f0b5781d39487d7Nico Weber  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}}
361cb2d742eb6635aeab6132ee5f0b5781d39487d7Nico Weber  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}}
371cb2d742eb6635aeab6132ee5f0b5781d39487d7Nico Weber  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}}
381cb2d742eb6635aeab6132ee5f0b5781d39487d7Nico Weber
391cb2d742eb6635aeab6132ee5f0b5781d39487d7Nico Weber  // FIXME: suggest replacing with "foo"[5]
401cb2d742eb6635aeab6132ee5f0b5781d39487d7Nico Weber  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}}
411cb2d742eb6635aeab6132ee5f0b5781d39487d7Nico Weber  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}}
421cb2d742eb6635aeab6132ee5f0b5781d39487d7Nico Weber
431cb2d742eb6635aeab6132ee5f0b5781d39487d7Nico Weber  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}}
441cb2d742eb6635aeab6132ee5f0b5781d39487d7Nico Weber
451cb2d742eb6635aeab6132ee5f0b5781d39487d7Nico Weber  // Should not warn.
461cb2d742eb6635aeab6132ee5f0b5781d39487d7Nico Weber  consume(&("foo"[3]));
471cb2d742eb6635aeab6132ee5f0b5781d39487d7Nico Weber  consume(&("foo"[index]));
481cb2d742eb6635aeab6132ee5f0b5781d39487d7Nico Weber  consume(&("foo"[kMyEnum]));
491cb2d742eb6635aeab6132ee5f0b5781d39487d7Nico Weber  consume("foo" + kMySmallEnum);
501cb2d742eb6635aeab6132ee5f0b5781d39487d7Nico Weber  consume(kMySmallEnum + "foo");
511cb2d742eb6635aeab6132ee5f0b5781d39487d7Nico Weber
521cb2d742eb6635aeab6132ee5f0b5781d39487d7Nico Weber  consume(L"foo" + 2);
531cb2d742eb6635aeab6132ee5f0b5781d39487d7Nico Weber
541cb2d742eb6635aeab6132ee5f0b5781d39487d7Nico Weber  consume("foo" + 3);  // Points at the \0
551cb2d742eb6635aeab6132ee5f0b5781d39487d7Nico Weber  consume("foo" + 4);  // Points 1 past the \0, which is legal too.
561cb2d742eb6635aeab6132ee5f0b5781d39487d7Nico Weber  consume("\pfoo" + 4);  // Pascal strings don't have a trailing \0, but they
571cb2d742eb6635aeab6132ee5f0b5781d39487d7Nico Weber                         // have a leading length byte, so this is fine too.
581cb2d742eb6635aeab6132ee5f0b5781d39487d7Nico Weber
591cb2d742eb6635aeab6132ee5f0b5781d39487d7Nico Weber  consume("foo" + kMyOperatorOverloadedEnum);
601cb2d742eb6635aeab6132ee5f0b5781d39487d7Nico Weber  consume(kMyOperatorOverloadedEnum + "foo");
611cb2d742eb6635aeab6132ee5f0b5781d39487d7Nico Weber
621cb2d742eb6635aeab6132ee5f0b5781d39487d7Nico Weber  #define A "foo"
631cb2d742eb6635aeab6132ee5f0b5781d39487d7Nico Weber  #define B "bar"
641cb2d742eb6635aeab6132ee5f0b5781d39487d7Nico Weber  consume(A B + sizeof(A) - 1);
651cb2d742eb6635aeab6132ee5f0b5781d39487d7Nico Weber}
661cb2d742eb6635aeab6132ee5f0b5781d39487d7Nico Weber
670e2c34f92f00628d48968dfea096d36381f494cbStephen Hinestemplate <typename T>
680e2c34f92f00628d48968dfea096d36381f494cbStephen Hinesvoid PR21848() {
690e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  (void)(sizeof(T) + ""); // expected-warning {{to a string does not append to the string}} expected-note {{use array indexing to silence this warning}}
700e2c34f92f00628d48968dfea096d36381f494cbStephen Hines}
710e2c34f92f00628d48968dfea096d36381f494cbStephen Hinestemplate void PR21848<int>(); // expected-note {{in instantiation of function template specialization 'PR21848<int>' requested here}}
72