[cfe-commits] r127596 - in /cfe/trunk: lib/Sema/SemaDecl.cpp lib/Sema/SemaExprCXX.cpp lib/Sema/SemaType.cpp test/CXX/except/except.spec/p15.cpp
Douglas Gregor
dgregor at apple.com
Mon Mar 14 11:45:30 PDT 2011
On Mar 14, 2011, at 11:08 AM, Sebastian Redl wrote:
> Author: cornedbee
> Date: Mon Mar 14 13:08:30 2011
> New Revision: 127596
>
> URL: http://llvm.org/viewvc/llvm-project?rev=127596&view=rev
> Log:
> Make deallocation functions implicitly noexcept in C++0x.
This is moderately terrifying, since throwing destructors (which were permitted in C++98/03) will now terminate(). We might want to put this under a flag, and even consider diagnosing the common cases (e.g., warn about a throw expression that occurs in a destructor).
- Doug
> Added:
> cfe/trunk/test/CXX/except/except.spec/p15.cpp
> Modified:
> cfe/trunk/lib/Sema/SemaDecl.cpp
> cfe/trunk/lib/Sema/SemaExprCXX.cpp
> cfe/trunk/lib/Sema/SemaType.cpp
>
> Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=127596&r1=127595&r2=127596&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaDecl.cpp Mon Mar 14 13:08:30 2011
> @@ -3733,7 +3733,7 @@
> }
>
> bool isStatic = SC == SC_Static;
> -
> +
> // [class.free]p1:
> // Any allocation function for a class T is a static member
> // (even if not explicitly declared static).
> @@ -3746,7 +3746,7 @@
> if (Name.getCXXOverloadedOperator() == OO_Delete ||
> Name.getCXXOverloadedOperator() == OO_Array_Delete)
> isStatic = true;
> -
> +
> // This is a C++ method declaration.
> NewFD = CXXMethodDecl::Create(Context, cast<CXXRecordDecl>(DC),
> D.getSourceRange().getBegin(),
>
> Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=127596&r1=127595&r2=127596&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Mon Mar 14 13:08:30 2011
> @@ -1404,11 +1404,18 @@
> /// DeclareGlobalNewDelete - Declare the global forms of operator new and
> /// delete. These are:
> /// @code
> +/// // C++03:
> /// void* operator new(std::size_t) throw(std::bad_alloc);
> /// void* operator new[](std::size_t) throw(std::bad_alloc);
> /// void operator delete(void *) throw();
> /// void operator delete[](void *) throw();
> +/// // C++0x:
> +/// void* operator new(std::size_t);
> +/// void* operator new[](std::size_t);
> +/// void operator delete(void *);
> +/// void operator delete[](void *);
> /// @endcode
> +/// C++0x operator delete is implicitly noexcept.
> /// Note that the placement and nothrow forms of new are *not* implicitly
> /// declared. Their use requires including \<new\>.
> void Sema::DeclareGlobalNewDelete() {
> @@ -1420,10 +1427,16 @@
> // implicitly declared in global scope in each translation unit of a
> // program
> //
> + // C++03:
> // void* operator new(std::size_t) throw(std::bad_alloc);
> // void* operator new[](std::size_t) throw(std::bad_alloc);
> // void operator delete(void*) throw();
> // void operator delete[](void*) throw();
> + // C++0x:
> + // void* operator new(std::size_t);
> + // void* operator new[](std::size_t);
> + // void operator delete(void*);
> + // void operator delete[](void*);
> //
> // These implicit declarations introduce only the function names operator
> // new, operator new[], operator delete, operator delete[].
> @@ -1432,7 +1445,9 @@
> // "std" or "bad_alloc" as necessary to form the exception specification.
> // However, we do not make these implicit declarations visible to name
> // lookup.
> - if (!StdBadAlloc) {
> + // Note that the C++0x versions of operator delete are deallocation functions,
> + // and thus are implicitly noexcept.
> + if (!StdBadAlloc && !getLangOptions().CPlusPlus0x) {
> // The "std::bad_alloc" class has not yet been declared, so build it
> // implicitly.
> StdBadAlloc = CXXRecordDecl::Create(Context, TTK_Class,
> @@ -1495,18 +1510,21 @@
> bool HasBadAllocExceptionSpec
> = (Name.getCXXOverloadedOperator() == OO_New ||
> Name.getCXXOverloadedOperator() == OO_Array_New);
> - if (HasBadAllocExceptionSpec) {
> + if (HasBadAllocExceptionSpec && !getLangOptions().CPlusPlus0x) {
> assert(StdBadAlloc && "Must have std::bad_alloc declared");
> BadAllocType = Context.getTypeDeclType(getStdBadAlloc());
> }
>
> FunctionProtoType::ExtProtoInfo EPI;
> if (HasBadAllocExceptionSpec) {
> - EPI.ExceptionSpecType = EST_Dynamic;
> - EPI.NumExceptions = 1;
> - EPI.Exceptions = &BadAllocType;
> + if (!getLangOptions().CPlusPlus0x) {
> + EPI.ExceptionSpecType = EST_Dynamic;
> + EPI.NumExceptions = 1;
> + EPI.Exceptions = &BadAllocType;
> + }
> } else {
> - EPI.ExceptionSpecType = EST_DynamicNone;
> + EPI.ExceptionSpecType = getLangOptions().CPlusPlus0x ?
> + EST_BasicNoexcept : EST_DynamicNone;
> }
>
> QualType FnType = Context.getFunctionType(Return, &Argument, 1, EPI);
>
> Modified: cfe/trunk/lib/Sema/SemaType.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=127596&r1=127595&r2=127596&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Sema/SemaType.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaType.cpp Mon Mar 14 13:08:30 2011
> @@ -1494,9 +1494,19 @@
>
> TypeProcessingState state(*this, D);
>
> + // In C++0x, deallocation functions (normal and array operator delete)
> + // are implicitly noexcept.
> + bool ImplicitlyNoexcept = false;
> +
> switch (D.getName().getKind()) {
> - case UnqualifiedId::IK_Identifier:
> case UnqualifiedId::IK_OperatorFunctionId:
> + if (getLangOptions().CPlusPlus0x) {
> + OverloadedOperatorKind OO = D.getName().OperatorFunctionId.Operator;
> + if (OO == OO_Delete || OO == OO_Array_Delete)
> + ImplicitlyNoexcept = true;
> + }
> + // Intentional fall-through.
> + case UnqualifiedId::IK_Identifier:
> case UnqualifiedId::IK_LiteralOperatorId:
> case UnqualifiedId::IK_TemplateId:
> T = ConvertDeclSpecToType(*this, state);
> @@ -1917,6 +1927,10 @@
> else
> EPI.NoexceptExpr = NoexceptExpr;
> }
> + } else if (FTI.getExceptionSpecType() == EST_None &&
> + ImplicitlyNoexcept && chunkIndex == 0) {
> + // Only the outermost chunk is marked noexcept, of course.
> + EPI.ExceptionSpecType = EST_BasicNoexcept;
> }
>
> T = Context.getFunctionType(T, ArgTys.data(), ArgTys.size(), EPI);
>
> Added: cfe/trunk/test/CXX/except/except.spec/p15.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/except/except.spec/p15.cpp?rev=127596&view=auto
> ==============================================================================
> --- cfe/trunk/test/CXX/except/except.spec/p15.cpp (added)
> +++ cfe/trunk/test/CXX/except/except.spec/p15.cpp Mon Mar 14 13:08:30 2011
> @@ -0,0 +1,24 @@
> +// RUN: %clang_cc1 -std=c++0x -fexceptions -fcxx-exceptions -fsyntax-only -verify %s
> +
> +// 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*) noexcept;
> +void operator delete[](void*) noexcept;
> +
> +// Same goes for explicit declarations.
> +void operator delete(void*, float);
> +void operator delete(void*, float) noexcept;
> +
> +void operator delete[](void*, float);
> +void operator delete[](void*, float) noexcept;
> +
> +// But explicit specs stay.
> +void operator delete(void*, double) throw(int); // expected-note {{previous}}
> +void operator delete(void*, double) noexcept; // expected-error {{does not match}}
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
More information about the cfe-commits
mailing list