[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
Sebastian Redl
sebastian.redl at getdesigned.at
Mon Mar 14 11:08:30 PDT 2011
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.
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}}
More information about the cfe-commits
mailing list