1*0a6a1f1dSLionel Sambuc // RUN: %clang_cc1 -std=c++11 -triple %itanium_abi_triple -fsyntax-only -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -verify %s 2*0a6a1f1dSLionel Sambuc // RUN: %clang_cc1 -std=c++11 -triple %ms_abi_triple -DMSABI -fsyntax-only -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -verify %s 3f4a2713aSLionel Sambuc class A { 4f4a2713aSLionel Sambuc public: 5f4a2713aSLionel Sambuc ~A(); 6f4a2713aSLionel Sambuc }; 7f4a2713aSLionel Sambuc 8f4a2713aSLionel Sambuc class B { 9f4a2713aSLionel Sambuc public: ~B()10f4a2713aSLionel Sambuc ~B() { } 11f4a2713aSLionel Sambuc }; 12f4a2713aSLionel Sambuc 13f4a2713aSLionel Sambuc class C { 14f4a2713aSLionel Sambuc public: 15f4a2713aSLionel Sambuc (~C)() { } 16f4a2713aSLionel Sambuc }; 17f4a2713aSLionel Sambuc 18f4a2713aSLionel Sambuc struct D { ~DD19f4a2713aSLionel Sambuc static void ~D(int, ...) const { } // \ 20f4a2713aSLionel Sambuc // expected-error{{static member function cannot have 'const' qualifier}} \ 21f4a2713aSLionel Sambuc // expected-error{{destructor cannot be declared 'static'}} \ 22f4a2713aSLionel Sambuc // expected-error{{destructor cannot have any parameters}} \ 23f4a2713aSLionel Sambuc // expected-error{{destructor cannot be variadic}} \ 24f4a2713aSLionel Sambuc // expected-error{{destructor cannot have a return type}} \ 25f4a2713aSLionel Sambuc // expected-error{{'const' qualifier is not allowed on a destructor}} 26f4a2713aSLionel Sambuc }; 27f4a2713aSLionel Sambuc 28f4a2713aSLionel Sambuc struct D2 { ~D2D229f4a2713aSLionel Sambuc void ~D2() { } // \ 30f4a2713aSLionel Sambuc // expected-error{{destructor cannot have a return type}} 31f4a2713aSLionel Sambuc }; 32f4a2713aSLionel Sambuc 33f4a2713aSLionel Sambuc 34f4a2713aSLionel Sambuc struct E; 35f4a2713aSLionel Sambuc 36f4a2713aSLionel Sambuc typedef E E_typedef; 37f4a2713aSLionel Sambuc struct E { 38f4a2713aSLionel Sambuc ~E_typedef(); // expected-error{{destructor cannot be declared using a typedef 'E_typedef' (aka 'E') of the class name}} 39f4a2713aSLionel Sambuc }; 40f4a2713aSLionel Sambuc 41f4a2713aSLionel Sambuc struct F { 42f4a2713aSLionel Sambuc (~F)(); // expected-note {{previous declaration is here}} 43f4a2713aSLionel Sambuc ~F(); // expected-error {{destructor cannot be redeclared}} 44f4a2713aSLionel Sambuc }; 45f4a2713aSLionel Sambuc 46f4a2713aSLionel Sambuc ~; // expected-error {{expected a class name after '~' to name a destructor}} 47f4a2713aSLionel Sambuc ~undef(); // expected-error {{expected the class name after '~' to name a destructor}} 48f4a2713aSLionel Sambuc ~operator+(int, int); // expected-error {{expected a class name after '~' to name a destructor}} ~F()49f4a2713aSLionel Sambuc~F(){} // expected-error {{destructor must be a non-static member function}} 50f4a2713aSLionel Sambuc 51f4a2713aSLionel Sambuc struct G { 52f4a2713aSLionel Sambuc ~G(); 53f4a2713aSLionel Sambuc }; 54f4a2713aSLionel Sambuc ~G()55f4a2713aSLionel SambucG::~G() { } 56f4a2713aSLionel Sambuc 57f4a2713aSLionel Sambuc // <rdar://problem/6841210> 58f4a2713aSLionel Sambuc struct H { ~HH59f4a2713aSLionel Sambuc ~H(void) { } 60f4a2713aSLionel Sambuc }; 61f4a2713aSLionel Sambuc 62f4a2713aSLionel Sambuc struct X {}; 63f4a2713aSLionel Sambuc 64f4a2713aSLionel Sambuc struct Y { 65f4a2713aSLionel Sambuc ~X(); // expected-error {{expected the class name after '~' to name the enclosing class}} 66f4a2713aSLionel Sambuc }; 67f4a2713aSLionel Sambuc 68f4a2713aSLionel Sambuc namespace PR6421 { 69f4a2713aSLionel Sambuc class T; // expected-note{{forward declaration}} 70f4a2713aSLionel Sambuc 71f4a2713aSLionel Sambuc class QGenericArgument // expected-note{{declared here}} 72f4a2713aSLionel Sambuc { 73f4a2713aSLionel Sambuc template<typename U> foo(T t)74f4a2713aSLionel Sambuc void foo(T t) // expected-error{{variable has incomplete type}} 75f4a2713aSLionel Sambuc { } 76f4a2713aSLionel Sambuc disconnect()77f4a2713aSLionel Sambuc void disconnect() 78f4a2713aSLionel Sambuc { 79f4a2713aSLionel Sambuc T* t; 80f4a2713aSLionel Sambuc bob<QGenericArgument>(t); // expected-error{{undeclared identifier 'bob'}} \ 81f4a2713aSLionel Sambuc // expected-error{{does not refer to a value}} 82f4a2713aSLionel Sambuc } 83f4a2713aSLionel Sambuc }; 84f4a2713aSLionel Sambuc } 85f4a2713aSLionel Sambuc 86f4a2713aSLionel Sambuc namespace PR6709 { 87*0a6a1f1dSLionel Sambuc #ifdef MSABI 88*0a6a1f1dSLionel Sambuc // This bug, "Clang instantiates destructor for function argument" is intended 89*0a6a1f1dSLionel Sambuc // behaviour in the Microsoft ABI because the callee needs to destruct the arguments. 90*0a6a1f1dSLionel Sambuc // expected-error@+3 {{indirection requires pointer operand ('int' invalid)}} 91*0a6a1f1dSLionel Sambuc // expected-note@+3 {{in instantiation of member function 'PR6709::X<int>::~X' requested here}} 92*0a6a1f1dSLionel Sambuc #endif ~X()93f4a2713aSLionel Sambuc template<class T> class X { T v; ~X() { ++*v; } }; a(X<int> x)94f4a2713aSLionel Sambuc void a(X<int> x) {} 95f4a2713aSLionel Sambuc } 96f4a2713aSLionel Sambuc 97f4a2713aSLionel Sambuc struct X0 { virtual ~X0() throw(); }; 98f4a2713aSLionel Sambuc struct X1 : public X0 { }; 99f4a2713aSLionel Sambuc 100f4a2713aSLionel Sambuc // Make sure we instantiate operator deletes when building a virtual 101f4a2713aSLionel Sambuc // destructor. 102f4a2713aSLionel Sambuc namespace test6 { 103f4a2713aSLionel Sambuc template <class T> class A { 104f4a2713aSLionel Sambuc public: 105f4a2713aSLionel Sambuc void *operator new(__SIZE_TYPE__); operator delete(void * p)106f4a2713aSLionel Sambuc void operator delete(void *p) { 107f4a2713aSLionel Sambuc T::deleteIt(p); // expected-error {{type 'int' cannot be used prior to '::'}} 108f4a2713aSLionel Sambuc } 109f4a2713aSLionel Sambuc 110*0a6a1f1dSLionel Sambuc #ifdef MSABI 111*0a6a1f1dSLionel Sambuc // expected-note@+2 {{in instantiation of member function 'test6::A<int>::operator delete' requested here}} 112*0a6a1f1dSLionel Sambuc #endif ~A()113f4a2713aSLionel Sambuc virtual ~A() {} 114f4a2713aSLionel Sambuc }; 115f4a2713aSLionel Sambuc 116*0a6a1f1dSLionel Sambuc #ifndef MSABI 117*0a6a1f1dSLionel Sambuc // expected-note@+2 {{in instantiation of member function 'test6::A<int>::operator delete' requested here}} 118*0a6a1f1dSLionel Sambuc #endif 119*0a6a1f1dSLionel Sambuc class B : A<int> { B(); }; B()120f4a2713aSLionel Sambuc B::B() {} 121f4a2713aSLionel Sambuc } 122f4a2713aSLionel Sambuc 123f4a2713aSLionel Sambuc // Make sure classes are marked invalid when they have invalid 124f4a2713aSLionel Sambuc // members. This avoids a crash-on-invalid. 125f4a2713aSLionel Sambuc namespace test7 { 126f4a2713aSLionel Sambuc struct A { 127f4a2713aSLionel Sambuc ~A() const; // expected-error {{'const' qualifier is not allowed on a destructor}} 128f4a2713aSLionel Sambuc }; 129f4a2713aSLionel Sambuc struct B : A {}; 130f4a2713aSLionel Sambuc test()131f4a2713aSLionel Sambuc void test() { 132f4a2713aSLionel Sambuc B *b; 133f4a2713aSLionel Sambuc b->~B(); 134f4a2713aSLionel Sambuc } 135f4a2713aSLionel Sambuc } 136f4a2713aSLionel Sambuc 137f4a2713aSLionel Sambuc namespace nonvirtualdtor { 138f4a2713aSLionel Sambuc struct S1 { // expected-warning {{has virtual functions but non-virtual destructor}} 139f4a2713aSLionel Sambuc virtual void m(); 140f4a2713aSLionel Sambuc }; 141f4a2713aSLionel Sambuc 142f4a2713aSLionel Sambuc struct S2 { 143f4a2713aSLionel Sambuc ~S2(); // expected-warning {{has virtual functions but non-virtual destructor}} 144f4a2713aSLionel Sambuc virtual void m(); 145f4a2713aSLionel Sambuc }; 146f4a2713aSLionel Sambuc 147f4a2713aSLionel Sambuc struct S3 : public S1 { // expected-warning {{has virtual functions but non-virtual destructor}} 148f4a2713aSLionel Sambuc virtual void m(); 149f4a2713aSLionel Sambuc }; 150f4a2713aSLionel Sambuc 151f4a2713aSLionel Sambuc struct S4 : public S2 { // expected-warning {{has virtual functions but non-virtual destructor}} 152f4a2713aSLionel Sambuc virtual void m(); 153f4a2713aSLionel Sambuc }; 154f4a2713aSLionel Sambuc 155f4a2713aSLionel Sambuc struct B { 156f4a2713aSLionel Sambuc virtual ~B(); 157f4a2713aSLionel Sambuc virtual void m(); 158f4a2713aSLionel Sambuc }; 159f4a2713aSLionel Sambuc 160f4a2713aSLionel Sambuc struct S5 : public B { 161f4a2713aSLionel Sambuc virtual void m(); 162f4a2713aSLionel Sambuc }; 163f4a2713aSLionel Sambuc 164f4a2713aSLionel Sambuc struct S6 { 165f4a2713aSLionel Sambuc virtual void m(); 166f4a2713aSLionel Sambuc private: 167f4a2713aSLionel Sambuc ~S6(); 168f4a2713aSLionel Sambuc }; 169f4a2713aSLionel Sambuc 170f4a2713aSLionel Sambuc struct S7 { 171f4a2713aSLionel Sambuc virtual void m(); 172f4a2713aSLionel Sambuc protected: 173f4a2713aSLionel Sambuc ~S7(); 174f4a2713aSLionel Sambuc }; 175f4a2713aSLionel Sambuc 176f4a2713aSLionel Sambuc template<class T> class TS : public B { 177f4a2713aSLionel Sambuc virtual void m(); 178f4a2713aSLionel Sambuc }; 179f4a2713aSLionel Sambuc 180f4a2713aSLionel Sambuc TS<int> baz; 181f4a2713aSLionel Sambuc 182f4a2713aSLionel Sambuc template<class T> class TS2 { // expected-warning {{'nonvirtualdtor::TS2<int>' has virtual functions but non-virtual destructor}} 183f4a2713aSLionel Sambuc virtual void m(); 184f4a2713aSLionel Sambuc }; 185f4a2713aSLionel Sambuc 186f4a2713aSLionel Sambuc TS2<int> foo; // expected-note {{instantiation}} 187f4a2713aSLionel Sambuc } 188f4a2713aSLionel Sambuc 189f4a2713aSLionel Sambuc namespace dnvd { // delete-non-virtual-dtor warning 190f4a2713aSLionel Sambuc struct NP {}; 191f4a2713aSLionel Sambuc 192f4a2713aSLionel Sambuc struct B { // expected-warning {{has virtual functions but non-virtual destructor}} 193f4a2713aSLionel Sambuc virtual void foo(); 194f4a2713aSLionel Sambuc }; 195f4a2713aSLionel Sambuc 196f4a2713aSLionel Sambuc struct D: B {}; // expected-warning {{has virtual functions but non-virtual destructor}} 197f4a2713aSLionel Sambuc 198*0a6a1f1dSLionel Sambuc struct F final : B {}; 199f4a2713aSLionel Sambuc 200f4a2713aSLionel Sambuc struct VB { 201f4a2713aSLionel Sambuc virtual void foo(); 202f4a2713aSLionel Sambuc virtual ~VB(); 203f4a2713aSLionel Sambuc }; 204f4a2713aSLionel Sambuc 205f4a2713aSLionel Sambuc struct VD: VB {}; 206f4a2713aSLionel Sambuc 207f4a2713aSLionel Sambuc struct VF final: VB {}; 208f4a2713aSLionel Sambuc 209f4a2713aSLionel Sambuc template <typename T> 210f4a2713aSLionel Sambuc class simple_ptr { 211f4a2713aSLionel Sambuc public: simple_ptr(T * t)212f4a2713aSLionel Sambuc simple_ptr(T* t): _ptr(t) {} ~simple_ptr()213f4a2713aSLionel Sambuc ~simple_ptr() { delete _ptr; } // \ 214f4a2713aSLionel Sambuc // expected-warning {{delete called on 'dnvd::B' that has virtual functions but non-virtual destructor}} \ 215f4a2713aSLionel Sambuc // expected-warning {{delete called on 'dnvd::D' that has virtual functions but non-virtual destructor}} operator *() const216f4a2713aSLionel Sambuc T& operator*() const { return *_ptr; } 217f4a2713aSLionel Sambuc private: 218f4a2713aSLionel Sambuc T* _ptr; 219f4a2713aSLionel Sambuc }; 220f4a2713aSLionel Sambuc 221f4a2713aSLionel Sambuc template <typename T> 222f4a2713aSLionel Sambuc class simple_ptr2 { 223f4a2713aSLionel Sambuc public: simple_ptr2(T * t)224f4a2713aSLionel Sambuc simple_ptr2(T* t): _ptr(t) {} ~simple_ptr2()225f4a2713aSLionel Sambuc ~simple_ptr2() { delete _ptr; } // expected-warning {{delete called on 'dnvd::B' that has virtual functions but non-virtual destructor}} operator *() const226f4a2713aSLionel Sambuc T& operator*() const { return *_ptr; } 227f4a2713aSLionel Sambuc private: 228f4a2713aSLionel Sambuc T* _ptr; 229f4a2713aSLionel Sambuc }; 230f4a2713aSLionel Sambuc 231f4a2713aSLionel Sambuc void use(B&); 232f4a2713aSLionel Sambuc void use(VB&); 233f4a2713aSLionel Sambuc nowarnstack()234f4a2713aSLionel Sambucvoid nowarnstack() { 235f4a2713aSLionel Sambuc B b; use(b); 236f4a2713aSLionel Sambuc D d; use(d); 237f4a2713aSLionel Sambuc F f; use(f); 238f4a2713aSLionel Sambuc VB vb; use(vb); 239f4a2713aSLionel Sambuc VD vd; use(vd); 240f4a2713aSLionel Sambuc VF vf; use(vf); 241f4a2713aSLionel Sambuc } 242f4a2713aSLionel Sambuc nowarnnonpoly()243f4a2713aSLionel Sambucvoid nowarnnonpoly() { 244f4a2713aSLionel Sambuc { 245f4a2713aSLionel Sambuc NP* np = new NP(); 246f4a2713aSLionel Sambuc delete np; 247f4a2713aSLionel Sambuc } 248f4a2713aSLionel Sambuc { 249f4a2713aSLionel Sambuc NP* np = new NP[4]; 250f4a2713aSLionel Sambuc delete[] np; 251f4a2713aSLionel Sambuc } 252f4a2713aSLionel Sambuc } 253f4a2713aSLionel Sambuc nowarnarray()254f4a2713aSLionel Sambucvoid nowarnarray() { 255f4a2713aSLionel Sambuc { 256f4a2713aSLionel Sambuc B* b = new B[4]; 257f4a2713aSLionel Sambuc delete[] b; 258f4a2713aSLionel Sambuc } 259f4a2713aSLionel Sambuc { 260f4a2713aSLionel Sambuc D* d = new D[4]; 261f4a2713aSLionel Sambuc delete[] d; 262f4a2713aSLionel Sambuc } 263f4a2713aSLionel Sambuc { 264f4a2713aSLionel Sambuc VB* vb = new VB[4]; 265f4a2713aSLionel Sambuc delete[] vb; 266f4a2713aSLionel Sambuc } 267f4a2713aSLionel Sambuc { 268f4a2713aSLionel Sambuc VD* vd = new VD[4]; 269f4a2713aSLionel Sambuc delete[] vd; 270f4a2713aSLionel Sambuc } 271f4a2713aSLionel Sambuc } 272f4a2713aSLionel Sambuc 273f4a2713aSLionel Sambuc template <typename T> nowarntemplate()274f4a2713aSLionel Sambucvoid nowarntemplate() { 275f4a2713aSLionel Sambuc { 276f4a2713aSLionel Sambuc T* t = new T(); 277f4a2713aSLionel Sambuc delete t; 278f4a2713aSLionel Sambuc } 279f4a2713aSLionel Sambuc { 280f4a2713aSLionel Sambuc T* t = new T[4]; 281f4a2713aSLionel Sambuc delete[] t; 282f4a2713aSLionel Sambuc } 283f4a2713aSLionel Sambuc } 284f4a2713aSLionel Sambuc nowarn0()285f4a2713aSLionel Sambucvoid nowarn0() { 286f4a2713aSLionel Sambuc { 287f4a2713aSLionel Sambuc F* f = new F(); 288f4a2713aSLionel Sambuc delete f; 289f4a2713aSLionel Sambuc } 290f4a2713aSLionel Sambuc { 291f4a2713aSLionel Sambuc VB* vb = new VB(); 292f4a2713aSLionel Sambuc delete vb; 293f4a2713aSLionel Sambuc } 294f4a2713aSLionel Sambuc { 295f4a2713aSLionel Sambuc VB* vb = new VD(); 296f4a2713aSLionel Sambuc delete vb; 297f4a2713aSLionel Sambuc } 298f4a2713aSLionel Sambuc { 299f4a2713aSLionel Sambuc VD* vd = new VD(); 300f4a2713aSLionel Sambuc delete vd; 301f4a2713aSLionel Sambuc } 302f4a2713aSLionel Sambuc { 303f4a2713aSLionel Sambuc VF* vf = new VF(); 304f4a2713aSLionel Sambuc delete vf; 305f4a2713aSLionel Sambuc } 306f4a2713aSLionel Sambuc } 307f4a2713aSLionel Sambuc warn0()308f4a2713aSLionel Sambucvoid warn0() { 309f4a2713aSLionel Sambuc { 310f4a2713aSLionel Sambuc B* b = new B(); 311f4a2713aSLionel Sambuc delete b; // expected-warning {{delete called on 'dnvd::B' that has virtual functions but non-virtual destructor}} 312f4a2713aSLionel Sambuc } 313f4a2713aSLionel Sambuc { 314f4a2713aSLionel Sambuc B* b = new D(); 315f4a2713aSLionel Sambuc delete b; // expected-warning {{delete called on 'dnvd::B' that has virtual functions but non-virtual destructor}} 316f4a2713aSLionel Sambuc } 317f4a2713aSLionel Sambuc { 318f4a2713aSLionel Sambuc D* d = new D(); 319f4a2713aSLionel Sambuc delete d; // expected-warning {{delete called on 'dnvd::D' that has virtual functions but non-virtual destructor}} 320f4a2713aSLionel Sambuc } 321f4a2713aSLionel Sambuc } 322f4a2713aSLionel Sambuc nowarn1()323f4a2713aSLionel Sambucvoid nowarn1() { 324f4a2713aSLionel Sambuc { 325f4a2713aSLionel Sambuc simple_ptr<F> f(new F()); 326f4a2713aSLionel Sambuc use(*f); 327f4a2713aSLionel Sambuc } 328f4a2713aSLionel Sambuc { 329f4a2713aSLionel Sambuc simple_ptr<VB> vb(new VB()); 330f4a2713aSLionel Sambuc use(*vb); 331f4a2713aSLionel Sambuc } 332f4a2713aSLionel Sambuc { 333f4a2713aSLionel Sambuc simple_ptr<VB> vb(new VD()); 334f4a2713aSLionel Sambuc use(*vb); 335f4a2713aSLionel Sambuc } 336f4a2713aSLionel Sambuc { 337f4a2713aSLionel Sambuc simple_ptr<VD> vd(new VD()); 338f4a2713aSLionel Sambuc use(*vd); 339f4a2713aSLionel Sambuc } 340f4a2713aSLionel Sambuc { 341f4a2713aSLionel Sambuc simple_ptr<VF> vf(new VF()); 342f4a2713aSLionel Sambuc use(*vf); 343f4a2713aSLionel Sambuc } 344f4a2713aSLionel Sambuc } 345f4a2713aSLionel Sambuc warn1()346f4a2713aSLionel Sambucvoid warn1() { 347f4a2713aSLionel Sambuc { 348f4a2713aSLionel Sambuc simple_ptr<B> b(new B()); // expected-note {{in instantiation of member function 'dnvd::simple_ptr<dnvd::B>::~simple_ptr' requested here}} 349f4a2713aSLionel Sambuc use(*b); 350f4a2713aSLionel Sambuc } 351f4a2713aSLionel Sambuc { 352f4a2713aSLionel Sambuc simple_ptr2<B> b(new D()); // expected-note {{in instantiation of member function 'dnvd::simple_ptr2<dnvd::B>::~simple_ptr2' requested here}} 353f4a2713aSLionel Sambuc use(*b); 354f4a2713aSLionel Sambuc } 355f4a2713aSLionel Sambuc { 356f4a2713aSLionel Sambuc simple_ptr<D> d(new D()); // expected-note {{in instantiation of member function 'dnvd::simple_ptr<dnvd::D>::~simple_ptr' requested here}} 357f4a2713aSLionel Sambuc use(*d); 358f4a2713aSLionel Sambuc } 359f4a2713aSLionel Sambuc } 360f4a2713aSLionel Sambuc } 361f4a2713aSLionel Sambuc 362f4a2713aSLionel Sambuc namespace PR9238 { 363f4a2713aSLionel Sambuc class B { public: ~B(); }; ~C()364f4a2713aSLionel Sambuc class C : virtual B { public: ~C() { } }; 365f4a2713aSLionel Sambuc } 366f4a2713aSLionel Sambuc 367f4a2713aSLionel Sambuc namespace PR7900 { 368f4a2713aSLionel Sambuc struct A { // expected-note 2{{type 'PR7900::A' is declared here}} 369f4a2713aSLionel Sambuc }; 370f4a2713aSLionel Sambuc struct B : public A { 371f4a2713aSLionel Sambuc }; foo()372f4a2713aSLionel Sambuc void foo() { 373f4a2713aSLionel Sambuc B b; 374f4a2713aSLionel Sambuc b.~B(); 375f4a2713aSLionel Sambuc b.~A(); // expected-error{{destructor type 'PR7900::A' in object destruction expression does not match the type 'PR7900::B' of the object being destroyed}} 376f4a2713aSLionel Sambuc (&b)->~A(); // expected-error{{destructor type 'PR7900::A' in object destruction expression does not match the type 'PR7900::B' of the object being destroyed}} 377f4a2713aSLionel Sambuc } 378f4a2713aSLionel Sambuc } 379f4a2713aSLionel Sambuc 380f4a2713aSLionel Sambuc namespace PR16892 { 381f4a2713aSLionel Sambuc auto p = &A::~A; // expected-error{{taking the address of a destructor}} 382f4a2713aSLionel Sambuc } 383*0a6a1f1dSLionel Sambuc 384*0a6a1f1dSLionel Sambuc namespace PR20238 { 385*0a6a1f1dSLionel Sambuc struct S { ~SPR20238::S386*0a6a1f1dSLionel Sambuc volatile ~S() { } // expected-error{{destructor cannot have a return type}} 387*0a6a1f1dSLionel Sambuc }; 388*0a6a1f1dSLionel Sambuc } 389