// RUN: %clang_cc1 -fsyntax-only -verify=compat,expected -Wunterminated-string-initialization %s -x c // RUN: %clang_cc1 -fsyntax-only -verify=cxx -Wunterminated-string-initialization %s -x c++ // REQUIRES: !system-linux #ifndef __cplusplus typedef __CHAR16_TYPE__ char16_t; typedef __CHAR32_TYPE__ char32_t; typedef __WCHAR_TYPE__ wchar_t; #endif // C++ is stricter so the following cases should be warned about. In // C, the following examples are fine. char foo3[3] = "fo\0"; // cxx-error {{initializer-string for char array is too long, array size is 3 but initializer has size 4 (including the null terminating character)}} char foo1[1] = "\0"; // cxx-error {{initializer-string for char array is too long, array size is 1 but initializer has size 2 (including the null terminating character)}} struct S { char buf[3]; char fub[3]; } s = { "ba\0", "bo\0" }; // cxx-error 2{{initializer-string for char array is too long, array size is 3 but initializer has size 4 (including the null terminating character)}} #pragma clang diagnostic push #pragma clang diagnostic warning "-Wc++-compat" // Test different encodings: signed char scfoo[3] = "fo\0"; // cxx-error {{initializer-string for char array is too long, array size is 3 but initializer has size 4 (including the null terminating character)}} \ compat-warning {{initializer-string for character array is too long for C++, array size is 3 but initializer has size 4 (including the null terminating character)}} unsigned char ucfoo[3] = "fo\0"; // cxx-error {{initializer-string for char array is too long, array size is 3 but initializer has size 4 (including the null terminating character)}} \ compat-warning {{initializer-string for character array is too long for C++, array size is 3 but initializer has size 4 (including the null terminating character)}} wchar_t wcfoo[3] = L"fo\0"; // cxx-error {{initializer-string for char array is too long, array size is 3 but initializer has size 4 (including the null terminating character)}} \ compat-warning {{initializer-string for character array is too long for C++, array size is 3 but initializer has size 4 (including the null terminating character)}} \ compat-warning {{identifier 'wchar_t' conflicts with a C++ keyword}} char16_t c16foo[3] = u"fo\0"; // cxx-error {{initializer-string for char array is too long, array size is 3 but initializer has size 4 (including the null terminating character)}} \ compat-warning {{initializer-string for character array is too long for C++, array size is 3 but initializer has size 4 (including the null terminating character)}} \ compat-warning {{identifier 'char16_t' conflicts with a C++ keyword}} char32_t c32foo[3] = U"fo\0"; // cxx-error {{initializer-string for char array is too long, array size is 3 but initializer has size 4 (including the null terminating character)}} \ compat-warning {{initializer-string for character array is too long for C++, array size is 3 but initializer has size 4 (including the null terminating character)}} \ compat-warning {{identifier 'char32_t' conflicts with a C++ keyword}} #pragma clang diagnostic pop // Test list initializer: signed char scfoo_lst[3] = {'f', 'o', '\0'}; unsigned char ucfoo_lst[3] = {'f', 'o', '\0'}; wchar_t wcfoo_lst[3] = {L'f', L'o', L'\0'}; char16_t c16foo_lst[3] = {u'f', u'o', u'\0'}; char32_t c32foo_lst[3] = {U'f', U'o', U'\0'}; // Declaring an array of size 0 is invalid by C standard but compilers // may allow it: char a[0] = ""; // expected-warning {{initializer-string for character array is too long, array size is 0 but initializer has size 1 (including the null terminating character); did you mean to use the 'nonstring' attribute?}} \ cxx-error {{initializer-string for char array is too long, array size is 0 but initializer has size 1 (including the null terminating character)}} char b[1] = ""; // no warn