From c7fb225cdc4662535340acb5ee0749a5c6d3c7d3 Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Fri, 7 Feb 2014 22:51:16 +0000 Subject: [PATCH] PR16638, DR1552: the exception specification on an implicitly-declared 'operator delete' or 'operator delete[]' is an explicit exception specification. Therefore we should diagnose 'void operator delete(void*)' instead of 'void operator delete(void*) noexcept'. This diagnostic remains an ExtWarn, since in practice people don't always include the exception specification in such a declaration. llvm-svn: 201002 --- clang/lib/Sema/SemaExceptionSpec.cpp | 9 ++++++--- clang/test/CXX/except/except.spec/p15.cpp | 20 +++++++++++-------- .../SemaCXX/cxx0x-cursory-default-delete.cpp | 2 +- 3 files changed, 19 insertions(+), 12 deletions(-) diff --git a/clang/lib/Sema/SemaExceptionSpec.cpp b/clang/lib/Sema/SemaExceptionSpec.cpp index 2eee07c0afdf..1c2a8dbc3012 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 fcf12357f916..acf4426a8eb5 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 94d5c297efa8..07a784226640 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}} -- GitLab