diff --git a/clang/lib/Sema/SemaExceptionSpec.cpp b/clang/lib/Sema/SemaExceptionSpec.cpp index 2eee07c0afdf1f4d20ef9932832004b472c1bee4..1c2a8dbc3012750d4d7db2d37cbac01a095d8987 100644 --- a/clang/lib/Sema/SemaExceptionSpec.cpp +++ b/clang/lib/Sema/SemaExceptionSpec.cpp @@ -140,10 +140,13 @@ static bool hasImplicitExceptionSpec(FunctionDecl *Decl) { Decl->getDeclName().getCXXOverloadedOperator() != OO_Array_Delete) return false; - // If the user didn't declare the function, its exception specification must - // be implicit. + // For a function that the user didn't declare: + // - if this is a destructor, its exception specification is implicit. + // - if this is 'operator delete' or 'operator delete[]', the exception + // specification is as-if an explicit exception specification was given + // (per [basic.stc.dynamic]p2). if (!Decl->getTypeSourceInfo()) - return true; + return isa(Decl); const FunctionProtoType *Ty = Decl->getTypeSourceInfo()->getType()->getAs(); diff --git a/clang/test/CXX/except/except.spec/p15.cpp b/clang/test/CXX/except/except.spec/p15.cpp index fcf12357f9162e38d28ae0e272081eb32f66c2f0..acf4426a8eb56091e73c056416f08c5fd6527450 100644 --- a/clang/test/CXX/except/except.spec/p15.cpp +++ b/clang/test/CXX/except/except.spec/p15.cpp @@ -1,16 +1,20 @@ // RUN: %clang_cc1 -std=c++11 -fexceptions -fcxx-exceptions -fsyntax-only -verify %s +// RUN: %clang_cc1 -DUSE -std=c++11 -fexceptions -fcxx-exceptions -fsyntax-only -verify %s + +// Maybe force the implicit declaration of 'operator delete' and 'operator +// delete[]'. This should make no difference to anything! +#ifdef USE +void f(int *p) { + delete p; + delete [] p; +} +#endif // Deallocation functions are implicitly noexcept. // Thus, explicit specs aren't allowed to conflict. -void f() { - // Force implicit declaration of delete. - delete new int; - delete[] new int[1]; -} - -void operator delete(void*); -void operator delete[](void*); +void operator delete(void*); // expected-warning {{function previously declared with an explicit exception specification redeclared with an implicit exception specification}} +void operator delete[](void*); // expected-warning {{function previously declared with an explicit exception specification redeclared with an implicit exception specification}} static_assert(noexcept(operator delete(0)), ""); static_assert(noexcept(operator delete[](0)), ""); diff --git a/clang/test/SemaCXX/cxx0x-cursory-default-delete.cpp b/clang/test/SemaCXX/cxx0x-cursory-default-delete.cpp index 94d5c297efa83a142e5160741156d731e43266a7..07a7842266408a291b9206902a6905b9ed032dc9 100644 --- a/clang/test/SemaCXX/cxx0x-cursory-default-delete.cpp +++ b/clang/test/SemaCXX/cxx0x-cursory-default-delete.cpp @@ -83,4 +83,4 @@ S::S() __attribute((pure)) = default; using size_t = decltype(sizeof(0)); void *operator new(size_t) = delete; // expected-error {{deleted definition must be first declaration}} expected-note {{implicit}} -void operator delete(void *) = delete; // expected-error {{deleted definition must be first declaration}} expected-note {{implicit}} +void operator delete(void *) noexcept = delete; // expected-error {{deleted definition must be first declaration}} expected-note {{implicit}}