llvm-project/clang/test/SemaCXX/string-plus-int.cpp
David Majnemer 7e21745e22 Sema: Don't diagnose string + int if the int is value dependent
Don't send a value dependent expression into the expression evaluator,
HandleSizeof would crash.  Making HandleSizeof handle dependent types
would noisily warn about the operation even if everything turns out OK
after instantiation.

This fixes PR21848.

llvm-svn: 224240
2014-12-15 10:00:35 +00:00

72 lines
3.2 KiB
C++

// RUN: %clang_cc1 -fsyntax-only -verify -Wno-array-bounds %s -fpascal-strings
// RUN: %clang_cc1 -fdiagnostics-parseable-fixits -x c++ %s 2>&1 -Wno-array-bounds -fpascal-strings | FileCheck %s
void consume(const char* c) {}
void consume(const unsigned char* c) {}
void consume(const wchar_t* c) {}
void consumeChar(char c) {}
enum MyEnum {
kMySmallEnum = 1,
kMyEnum = 5
};
enum OperatorOverloadEnum {
kMyOperatorOverloadedEnum = 5
};
const char* operator+(const char* c, OperatorOverloadEnum e) {
return "yo";
}
const char* operator+(OperatorOverloadEnum e, const char* c) {
return "yo";
}
void f(int index) {
// Should warn.
// CHECK: fix-it:"{{.*}}":{31:11-31:11}:"&"
// CHECK: fix-it:"{{.*}}":{31:17-31:18}:"["
// CHECK: fix-it:"{{.*}}":{31:20-31:20}:"]"
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}}
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}}
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}}
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}}
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}}
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}}
// FIXME: suggest replacing with "foo"[5]
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}}
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}}
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}}
// Should not warn.
consume(&("foo"[3]));
consume(&("foo"[index]));
consume(&("foo"[kMyEnum]));
consume("foo" + kMySmallEnum);
consume(kMySmallEnum + "foo");
consume(L"foo" + 2);
consume("foo" + 3); // Points at the \0
consume("foo" + 4); // Points 1 past the \0, which is legal too.
consume("\pfoo" + 4); // Pascal strings don't have a trailing \0, but they
// have a leading length byte, so this is fine too.
consume("foo" + kMyOperatorOverloadedEnum);
consume(kMyOperatorOverloadedEnum + "foo");
#define A "foo"
#define B "bar"
consume(A B + sizeof(A) - 1);
}
template <typename T>
void PR21848() {
(void)(sizeof(T) + ""); // expected-warning {{to a string does not append to the string}} expected-note {{use array indexing to silence this warning}}
}
template void PR21848<int>(); // expected-note {{in instantiation of function template specialization 'PR21848<int>' requested here}}