1 // RUN: %clang_cc1 %s -std=c++1z -fsyntax-only -verify -pedantic 2 // RUN: %clang_cc1 %s -std=c++1z -fsyntax-only -verify -pedantic -fno-signed-char 3 4 # 4 "/usr/include/string.h" 1 3 4 5 extern "C" { 6 typedef decltype(sizeof(int)) size_t; 7 8 extern size_t strlen(const char *p); 9 10 extern int strcmp(const char *s1, const char *s2); 11 extern int strncmp(const char *s1, const char *s2, size_t n); 12 extern int memcmp(const char *s1, const char *s2, size_t n); // expected-note {{here}} 13 14 extern char *strchr(const char *s, int c); 15 extern void *memchr(const void *s, int c, size_t n); 16 } 17 18 # 19 "SemaCXX/constexpr-string.cpp" 2 19 namespace Strlen { 20 constexpr int n = __builtin_strlen("hello"); // ok 21 constexpr int m = strlen("hello"); // expected-error {{constant expression}} expected-note {{non-constexpr function 'strlen' cannot be used in a constant expression}} 22 23 // Make sure we can evaluate a call to strlen. 24 int arr[3]; // expected-note {{here}} 25 int k = arr[strlen("hello")]; // expected-warning {{array index 5}} 26 } 27 28 namespace StrcmpEtc { 29 constexpr char kFoobar[6] = {'f','o','o','b','a','r'}; 30 constexpr char kFoobazfoobar[12] = {'f','o','o','b','a','z','f','o','o','b','a','r'}; 31 32 static_assert(__builtin_strcmp("abab", "abab") == 0); 33 static_assert(__builtin_strcmp("abab", "abba") == -1); 34 static_assert(__builtin_strcmp("abab", "abaa") == 1); 35 static_assert(__builtin_strcmp("ababa", "abab") == 1); 36 static_assert(__builtin_strcmp("abab", "ababa") == -1); 37 static_assert(__builtin_strcmp("abab\0banana", "abab") == 0); 38 static_assert(__builtin_strcmp("abab", "abab\0banana") == 0); 39 static_assert(__builtin_strcmp("abab\0banana", "abab\0canada") == 0); 40 static_assert(__builtin_strcmp(0, "abab") == 0); // expected-error {{not an integral constant}} expected-note {{dereferenced null}} 41 static_assert(__builtin_strcmp("abab", 0) == 0); // expected-error {{not an integral constant}} expected-note {{dereferenced null}} 42 43 static_assert(__builtin_strcmp(kFoobar, kFoobazfoobar) == -1); // FIXME: Should we reject this? 44 static_assert(__builtin_strcmp(kFoobar, kFoobazfoobar + 6) == 0); // expected-error {{not an integral constant}} expected-note {{dereferenced one-past-the-end}} 45 46 static_assert(__builtin_strncmp("abaa", "abba", 5) == -1); 47 static_assert(__builtin_strncmp("abaa", "abba", 4) == -1); 48 static_assert(__builtin_strncmp("abaa", "abba", 3) == -1); 49 static_assert(__builtin_strncmp("abaa", "abba", 2) == 0); 50 static_assert(__builtin_strncmp("abaa", "abba", 1) == 0); 51 static_assert(__builtin_strncmp("abaa", "abba", 0) == 0); 52 static_assert(__builtin_strncmp(0, 0, 0) == 0); 53 static_assert(__builtin_strncmp("abab\0banana", "abab\0canada", 100) == 0); 54 55 static_assert(__builtin_strncmp(kFoobar, kFoobazfoobar, 6) == -1); 56 static_assert(__builtin_strncmp(kFoobar, kFoobazfoobar, 7) == -1); // FIXME: Should we reject this? 57 static_assert(__builtin_strncmp(kFoobar, kFoobazfoobar + 6, 6) == 0); 58 static_assert(__builtin_strncmp(kFoobar, kFoobazfoobar + 6, 7) == 0); // expected-error {{not an integral constant}} expected-note {{dereferenced one-past-the-end}} 59 60 static_assert(__builtin_memcmp("abaa", "abba", 3) == -1); 61 static_assert(__builtin_memcmp("abaa", "abba", 2) == 0); 62 static_assert(__builtin_memcmp(0, 0, 0) == 0); 63 static_assert(__builtin_memcmp("abab\0banana", "abab\0banana", 100) == 0); // expected-error {{not an integral constant}} expected-note {{dereferenced one-past-the-end}} 64 static_assert(__builtin_memcmp("abab\0banana", "abab\0canada", 100) == -1); // FIXME: Should we reject this? 65 static_assert(__builtin_memcmp("abab\0banana", "abab\0canada", 7) == -1); 66 static_assert(__builtin_memcmp("abab\0banana", "abab\0canada", 6) == -1); 67 static_assert(__builtin_memcmp("abab\0banana", "abab\0canada", 5) == 0); 68 69 constexpr int a = strcmp("hello", "world"); // expected-error {{constant expression}} expected-note {{non-constexpr function 'strcmp' cannot be used in a constant expression}} 70 constexpr int b = strncmp("hello", "world", 3); // expected-error {{constant expression}} expected-note {{non-constexpr function 'strncmp' cannot be used in a constant expression}} 71 constexpr int c = memcmp("hello", "world", 3); // expected-error {{constant expression}} expected-note {{non-constexpr function 'memcmp' cannot be used in a constant expression}} 72 } 73 74 namespace StrchrEtc { 75 constexpr const char *kStr = "abca\xff\0d"; 76 constexpr char kFoo[] = {'f', 'o', 'o'}; 77 static_assert(__builtin_strchr(kStr, 'a') == kStr); 78 static_assert(__builtin_strchr(kStr, 'b') == kStr + 1); 79 static_assert(__builtin_strchr(kStr, 'c') == kStr + 2); 80 static_assert(__builtin_strchr(kStr, 'd') == nullptr); 81 static_assert(__builtin_strchr(kStr, 'e') == nullptr); 82 static_assert(__builtin_strchr(kStr, '\0') == kStr + 5); 83 static_assert(__builtin_strchr(kStr, 'a' + 256) == nullptr); 84 static_assert(__builtin_strchr(kStr, 'a' - 256) == nullptr); 85 static_assert(__builtin_strchr(kStr, '\xff') == kStr + 4); 86 static_assert(__builtin_strchr(kStr, '\xff' + 256) == nullptr); 87 static_assert(__builtin_strchr(kStr, '\xff' - 256) == nullptr); 88 static_assert(__builtin_strchr(kFoo, 'o') == kFoo + 1); 89 static_assert(__builtin_strchr(kFoo, 'x') == nullptr); // expected-error {{not an integral constant}} expected-note {{dereferenced one-past-the-end}} 90 static_assert(__builtin_strchr(nullptr, 'x') == nullptr); // expected-error {{not an integral constant}} expected-note {{dereferenced null}} 91 92 static_assert(__builtin_memchr(kStr, 'a', 0) == nullptr); 93 static_assert(__builtin_memchr(kStr, 'a', 1) == kStr); 94 static_assert(__builtin_memchr(kStr, '\0', 5) == nullptr); 95 static_assert(__builtin_memchr(kStr, '\0', 6) == kStr + 5); 96 static_assert(__builtin_memchr(kStr, '\xff', 8) == kStr + 4); 97 static_assert(__builtin_memchr(kStr, '\xff' + 256, 8) == kStr + 4); 98 static_assert(__builtin_memchr(kStr, '\xff' - 256, 8) == kStr + 4); 99 static_assert(__builtin_memchr(kFoo, 'x', 3) == nullptr); 100 static_assert(__builtin_memchr(kFoo, 'x', 4) == nullptr); // expected-error {{not an integral constant}} expected-note {{dereferenced one-past-the-end}} 101 static_assert(__builtin_memchr(nullptr, 'x', 3) == nullptr); // expected-error {{not an integral constant}} expected-note {{dereferenced null}} 102 static_assert(__builtin_memchr(nullptr, 'x', 0) == nullptr); // FIXME: Should we reject this? 103 104 constexpr bool a = !strchr("hello", 'h'); // expected-error {{constant expression}} expected-note {{non-constexpr function 'strchr' cannot be used in a constant expression}} 105 constexpr bool b = !memchr("hello", 'h', 3); // expected-error {{constant expression}} expected-note {{non-constexpr function 'memchr' cannot be used in a constant expression}} 106 } 107