diff options
-rw-r--r-- | lib/Sema/SemaExceptionSpec.cpp | 9 | ||||
-rw-r--r-- | test/CXX/except/except.spec/p15.cpp | 20 | ||||
-rw-r--r-- | test/SemaCXX/cxx0x-cursory-default-delete.cpp | 2 |
3 files changed, 19 insertions, 12 deletions
diff --git a/lib/Sema/SemaExceptionSpec.cpp b/lib/Sema/SemaExceptionSpec.cpp index 2eee07c0af..1c2a8dbc30 100644 --- a/lib/Sema/SemaExceptionSpec.cpp +++ b/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<CXXDestructorDecl>(Decl); const FunctionProtoType *Ty = Decl->getTypeSourceInfo()->getType()->getAs<FunctionProtoType>(); diff --git a/test/CXX/except/except.spec/p15.cpp b/test/CXX/except/except.spec/p15.cpp index fcf12357f9..acf4426a8e 100644 --- a/test/CXX/except/except.spec/p15.cpp +++ b/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/test/SemaCXX/cxx0x-cursory-default-delete.cpp b/test/SemaCXX/cxx0x-cursory-default-delete.cpp index 94d5c297ef..07a7842266 100644 --- a/test/SemaCXX/cxx0x-cursory-default-delete.cpp +++ b/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}} |