[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