brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.3 KiB · 77466df Raw
129 lines · cpp
1// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++26 -triple x86_64-gnu-linux2// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++26 -triple x86_64-gnu-linux -fexperimental-new-constant-interpreter3 4template <bool Leak>5struct RAIIBase {6    constexpr RAIIBase(const char* in) {7        s = __builtin_strlen(in);8        d = new char[s + 1]; // expected-note 4{{allocation performed here was not deallocated}}9        for(int i = 0 ; i < s; i++)10            d[i] = in[i];11    }12    int s;13    char* d;14    constexpr unsigned long size() const {15        return s;16    }17    constexpr const char* data() const {18        return d;19    }20    constexpr ~RAIIBase() {21        if constexpr(!Leak)22            delete[] d;23    }24};25 26using RAII = RAIIBase<false>;27using RAIILeak = RAIIBase<true>;28 29void test_leaks(int i) {30    asm((RAII("nop")) : (RAII("+ir")) (i) : (RAII("g")) (i) : (RAII("memory")));31    asm((RAIILeak("nop"))); // expected-error {{the expression in this asm operand must be produced by a constant expression}}32    asm((RAII("nop"))33        : (RAIILeak("+ir")) (i) // expected-error {{the expression in this asm operand must be produced by a constant expression}}34        ::35    );36    asm((RAII("nop"))37        : (RAII("+ir")) (i)38        : (RAIILeak("g")) (i) // expected-error {{the expression in this asm operand must be produced by a constant expression}}39        :40    );41    asm((RAII("nop"))42        : (RAII("+ir")) (i)43        : (RAII("g")) (i)44        : (RAIILeak("memory")) // expected-error {{the expression in this asm operand must be produced by a constant expression}}45    );46}47 48struct NotAString{};49struct MessageInvalidSize {50    constexpr unsigned long size(int) const; // expected-note {{'size' declared here}}51    constexpr const char* data() const;52};53struct MessageInvalidData {54    constexpr unsigned long size() const;55    constexpr const char* data(int) const; // expected-note {{'data' declared here}}56};57 58 59struct WMessage {60    constexpr unsigned long long size() const {return 0;};61    constexpr const wchar_t* data() const {return L"";}62};63 64struct string_view {65  int S;66  const char* D;67  constexpr string_view() : S(0), D(0){}68  constexpr string_view(const char* Str) : S(__builtin_strlen(Str)), D(Str) {}69  constexpr string_view(int Size, const char* Str) : S(Size), D(Str) {}70  constexpr int size() const {71      return S;72  }73  constexpr const char* data() const {74      return D;75  }76};77 78 79void f() {80    asm(("")); // expected-error {{the expression in this asm operand must be a string literal or an object with 'data()' and 'size()' member functions}}81    asm((NotAString{})); // expected-error {{the string object in this asm operand is missing 'data()' and 'size()' member functions}}82    asm((MessageInvalidData{})); // expected-error {{the expression in this asm operand must have a 'data()' member function returning an object convertible to 'const char *'}} \83                                 // expected-error {{too few arguments to function call, expected 1, have 0}}84    asm((MessageInvalidSize{})); // expected-error {{the expression in this asm operand must have a 'size()' member function returning an object convertible to 'std::size_t'}} \85                                 // expected-error {{too few arguments to function call, expected 1, have 0}}86 87    asm((WMessage{})); // expected-error {{value of type 'const wchar_t *' is not implicitly convertible to 'const char *'}} \88                       // expected-error {{the expression in this asm operand must have a 'data()' member function returning an object convertible to 'const char *'}}89}90 91template <typename... U>92void test_packs() {93    asm((U{})); // expected-error {{expression contains unexpanded parameter pack 'U'}}94    asm("" : (U{})); // expected-error {{expression contains unexpanded parameter pack 'U'}}95    asm("" :: (U{})); // expected-error {{expression contains unexpanded parameter pack 'U'}}96    asm("" ::: (U{})); // expected-error {{expression contains unexpanded parameter pack 'U'}}97}98 99template <typename T>100void test_dependent1(int i) {101    asm((T{})); // #err-int102    asm("" : (T{"+g"})(i)); // #err-int2103    asm("" :: (T{"g"})(i)); // #err-int3104    asm("" ::: (T{"memory"})); // #err-int4105}106 107template void test_dependent1<int>(int);108// expected-note@-1 {{in instantiation of function template specialization}}109// expected-error@#err-int {{the expression in this asm operand must be a string literal or an object with 'data()' and 'size()' member functions}}110// expected-error@#err-int2 {{cannot initialize a value of type 'int' with an lvalue of type 'const char[3]'}}111// expected-error@#err-int3 {{cannot initialize a value of type 'int' with an lvalue of type 'const char[2]'}}112// expected-error@#err-int4 {{cannot initialize a value of type 'int' with an lvalue of type 'const char[7]'}}113 114template void test_dependent1<string_view>(int);115 116 117template <typename T>118void test_dependent2(int i) {119    asm("" : (T{"g"})(i)); // #err-invalid1120    asm("" :: (T{"+g"})(i)); // #err-invalid2121    asm("" ::: (T{"foo"})); // #err-invalid3122}123template void test_dependent2<string_view>(int);124// expected-note@-1 {{in instantiation of function template specialization}}125// expected-error@#err-invalid1 {{invalid output constraint 'g' in asm}}126// expected-error@#err-invalid2 {{invalid input constraint '+g' in asm}}127// expected-error@#err-invalid3 {{unknown register name 'foo' in asm}}128 129