brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.0 KiB · 55849d6 Raw
197 lines · cpp
1// RUN: %clang_cc1 -emit-llvm-only -verify -std=c++11 %s2struct A {};3 4enum Foo { F };5typedef Foo Bar; // expected-note{{type 'Bar' (aka 'Foo') found by destructor name lookup}}6 7typedef int Integer;8typedef double Double;9 10void g();11 12namespace N {13  typedef Foo Wibble;14  typedef int OtherInteger;15}16 17template <typename T>18void cv_test(const volatile T* cvt) {19  cvt->T::~T(); // no-warning20}21 22void f(A* a, Foo *f, int *i, double *d, int ii) {23  a->~A();24  a->A::~A();25 26  a->~foo(); // expected-error{{undeclared identifier 'foo' in destructor name}}27 28  a->~Bar(); // expected-error{{destructor type 'Bar' (aka 'Foo') in object destruction expression does not match the type 'A' of the object being destroyed}}29 30  f->~Bar();31  f->~Foo();32  i->~Bar(); // expected-error{{does not match}}33 34  g().~Bar(); // expected-error{{non-scalar}}35 36  f->::~Bar(); // expected-error {{not a structure or union}}37  f->::Bar::~Bar();38  f->N::~Wibble(); // expected-error{{'N' does not refer to a type}} expected-error{{'Wibble' does not refer to a type}}39 40  f->Bar::~Bar(17, 42); // expected-error{{cannot have any arguments}}41 42  i->~Integer();43  i->Integer::~Integer();44  i->N::~OtherInteger(); // expected-error{{'N' does not refer to a type name in pseudo-destructor expression; expected the name of type 'int'}}45                         // expected-error@-1{{'OtherInteger' does not refer to a type name in pseudo-destructor expression; expected the name of type 'int'}}46  i->N::OtherInteger::~OtherInteger();47  i->N::OtherInteger::~OtherInteger();48  i->N::OtherInteger::~Integer(); // expected-error{{'Integer' does not refer to a type name in pseudo-destructor expression; expected the name of type 'int'}}49  i->N::~Integer(); // expected-error{{'N' does not refer to a type name in pseudo-destructor expression; expected the name of type 'int'}}50  i->N::OtherInteger::~Integer(); // expected-error{{'Integer' does not refer to a type name in pseudo-destructor expression; expected the name of type 'int'}}51  i->Integer::~Double(); // expected-error{{the type of object expression ('int') does not match the type being destroyed ('Double' (aka 'double')) in pseudo-destructor expression}}52 53  ii->~Integer(); // expected-error{{member reference type 'int' is not a pointer; did you mean to use '.'?}}54  ii.~Integer();55 56  cv_test(a);57  cv_test(f);58  cv_test(i);59  cv_test(d);60}61 62 63typedef int Integer;64 65void destroy_without_call(int *ip) {66  ip->~Integer; // expected-error{{reference to pseudo-destructor must be called}}67}68 69void paren_destroy_with_call(int *ip) {70  (ip->~Integer)();71}72 73// PR553074namespace N1 {75  class X0 { };76}77 78void test_X0(N1::X0 &x0) {79  x0.~X0();80}81 82namespace PR11339 {83  template<class T>84  void destroy(T* p) {85    p->~T(); // ok86    p->~oops(); // expected-error{{undeclared identifier 'oops' in destructor name}}87  }88 89  template void destroy(int*); // expected-note{{in instantiation of function template specialization}}90}91 92template<typename T> using Id = T;93void AliasTemplate(int *p) {94  p->~Id<int>();95  p->template ~Id<int>(); // expected-error {{'template' keyword not permitted in destructor name}}96  (0).~Id<int>();97  (0).template ~Id<int>(); // expected-error {{'template' keyword not permitted in destructor name}}98}99 100namespace dotPointerAccess {101struct Base {102  virtual ~Base() {}103};104 105struct Derived : Base {106  ~Derived() {}107};108 109void test() {110  Derived d;111  static_cast<Base *>(&d).~Base(); // expected-error {{member reference type 'Base *' is a pointer; did you mean to use '->'}}112  d->~Derived(); // expected-error {{member reference type 'Derived' is not a pointer; did you mean to use '.'}}113}114 115typedef Derived *Foo;116 117void test2(Foo d) {118  d.~Foo(); // This is ok119  d.~Derived(); // expected-error {{member reference type 'Foo' (aka 'Derived *') is a pointer; did you mean to use '->'}}120}121}122 123int pr45294 = 1 .~undeclared_tempate_name<>(); // expected-error {{use of undeclared 'undeclared_tempate_name'}}124 125namespace TwoPhaseLookup {126  namespace NonTemplate {127    struct Y {};128    using G = Y;129    template<typename T> void f(T *p) { p->~G(); } // expected-error {{no member named '~Y'}}130    void h1(Y *p) { p->~G(); }131    void h2(Y *p) { f(p); }132    namespace N { struct G{}; }133    void h3(N::G *p) { p->~G(); }134    void h4(N::G *p) { f(p); } // expected-note {{instantiation of}}135  }136 137  namespace NonTemplateUndeclared {138    struct Y {};139    template<typename T> void f(T *p) { p->~G(); } // expected-error {{undeclared identifier 'G' in destructor name}}140    using G = Y;141    void h1(Y *p) { p->~G(); }142    void h2(Y *p) { f(p); } // expected-note {{instantiation of}}143    namespace N { struct G{}; }144    void h3(N::G *p) { p->~G(); }145    void h4(N::G *p) { f(p); }146  }147 148  namespace Template {149    template<typename T> struct Y {};150    template<class U> using G = Y<U>;151    template<typename T> void f(T *p) { p->~G<int>(); } // expected-error {{no member named '~Y'}}152    void h1(Y<int> *p) { p->~G<int>(); }153    void h2(Y<int> *p) { f(p); }154    namespace N { template<typename T> struct G {}; }155    void h3(N::G<int> *p) { p->~G<int>(); }156    void h4(N::G<int> *p) { f(p); } // expected-note {{instantiation of}}157  }158 159  namespace TemplateUndeclared {160    template<typename T> struct Y {};161    // FIXME: Formally, this is ill-formed before we hit any instantiation,162    // because we aren't supposed to treat the '<' as introducing a template163    // name.164    template<typename T> void f(T *p) { p->~G<int>(); } // expected-error {{no member named 'G'}}165    template<class U> using G = Y<U>;166    void h1(Y<int> *p) { p->~G<int>(); }167    void h2(Y<int> *p) { f(p); } // expected-note {{instantiation of}}168    namespace N { template<typename T> struct G {}; }169    void h3(N::G<int> *p) { p->~G<int>(); }170    void h4(N::G<int> *p) { f(p); }171  }172 173  namespace TemplateNamesNonTemplate {174    int A; // expected-note 2{{non-template here}}175    template<typename> int B; // expected-note 2{{variable template 'B' declared here}} expected-warning {{extension}}176    using C = int; // expected-note 2{{non-template here}}177 178    template<typename T> void f1(int *p) { p->~A<int>(); } // expected-error {{'A' does not refer to a template}}179    template<typename T> void f2(int *p) { p->~B<int>(); } // expected-error {{template name refers to non-type template 'B'}}180    template<typename T> void f3(int *p) { p->~C<int>(); } // expected-error {{'C' does not refer to a template}}181    template<typename T> void f4(int *p) { p->TemplateNamesNonTemplate::C::~A<int>(); } // expected-error {{'A' does not refer to a template}}182    template<typename T> void f5(int *p) { p->TemplateNamesNonTemplate::C::~B<int>(); } // expected-error {{template name refers to non-type template 'TemplateNamesNonTemplate::B'}}183    template<typename T> void f6(int *p) { p->TemplateNamesNonTemplate::C::~C<int>(); } // expected-error {{'C' does not refer to a template}}184  }185}186 187void destroy_array_element() {188  int arr[5];189  using T = int;190  arr->~T(); // ok, destroy arr[0].191}192 193void destroy_function() {194  using T = void();195  destroy_function->~T(); // expected-error {{object expression of non-scalar type 'void ()' cannot be used in a pseudo-destructor expression}}196}197