93 lines · cpp
1// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s -fcxx-exceptions -triple=x86_64-linux-gnu2// RUN: %clang_cc1 -fsyntax-only -std=c++20 -verify %s -fcxx-exceptions -triple=x86_64-linux-gnu3 4using size_t = decltype(sizeof(int));5 6int &operator ""_x1 (const char *);7double &operator ""_x1 (const char *, size_t);8double &i1 = "foo"_x1;9#if __cplusplus >= 202002L10using char8 = float;11float &operator ""_x1 (const char8_t *, size_t);12#else13using char8 = double;14#endif15char8 &i2 = u8"foo"_x1;16double &i3 = L"foo"_x1; // expected-error {{no matching literal operator for call to 'operator""_x1' with arguments of types 'const wchar_t *' and '__size_t' (aka 'unsigned long')}}17 18char &operator ""_x1(const wchar_t *, size_t);19char &i4 = L"foo"_x1; // ok20double &i5 = R"(foo)"_x1; // ok21char8 &i6 = u\228\23R\24"(foo)"\25_\26x\271; // ok28 29#if __cplusplus >= 202002L30template<int N> struct S {31 char a[N];32 constexpr S(const char (&r)[N]) {33 __builtin_memcpy(a, r, N);34 if (a[0] == 'x') throw "no";35 }36 constexpr ~S() {37 if (a[0] == 'y') throw "also no";38 }39};40 41// Check the produced contents are correct.42template<S s> constexpr const decltype(s) &operator""_str() { return s; }43static_assert(__builtin_strcmp("hello world"_str.a, "hello world") == 0);44 45template<S> float &operator""_s();46void no_fallback() {47 "hello"_s;48 // FIXME: It'd be useful to explain what candidates were found and why they didn't work.49 "xyzzy"_s; // expected-error {{no matching literal operator for call to 'operator""_s' with arguments of types 'const char *' and '__size_t' (aka 'unsigned long'), and no matching literal operator template}}50 "yello"_s; // expected-error {{no matching literal operator for call to 'operator""_s' with arguments of types 'const char *' and '__size_t' (aka 'unsigned long'), and no matching literal operator template}}51}52 53double &operator""_s(const char*, size_t);54void f() {55 float &a = "foo"_s;56 double &b = "xar"_s;57 double &c = "yar"_s;58}59 60template<S<4>> float &operator""_t();61double &operator""_t(const char*, size_t);62void g() {63 double &a = "fo"_t;64 float &b = "foo"_t;65 double &c = "fooo"_t;66}67 68template<int N> struct X {69 static constexpr int size = N;70 constexpr X(const char (&r)[N]) {}71};72template<X x> requires (x.size == 4) // expected-note {{because 'X<5>{}.size == 4' (5 == 4) evaluated to false}}73void operator""_x(); // expected-note {{constraints not satisfied}}74void operator""_x(const char*, size_t) = delete;75 76template<int N> requires (N == 4)77struct Y {78 constexpr Y(const char (&r)[N]) {}79};80template<Y> float &operator""_y();81void operator""_y(const char*, size_t) = delete; // expected-note {{deleted here}}82 83void test() {84 "foo"_x;85 "foo"_y;86 87 // We only check the template argument itself for validity, not the whole88 // call, when deciding whether to use the template or non-template form.89 "fooo"_x; // expected-error {{no matching function}}90 "fooo"_y; // expected-error {{deleted function}}91}92#endif93