From: Sebastian Redl Date: Mon, 14 Mar 2011 20:33:20 +0000 (+0000) Subject: Code generation for noexcept. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f86d5f2b888573f7d72d7eeae7237cf6c5080958;p=clang Code generation for noexcept. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@127617 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CGException.cpp b/lib/CodeGen/CGException.cpp index f05bc700b4..7fdfe70042 100644 --- a/lib/CodeGen/CGException.cpp +++ b/lib/CodeGen/CGException.cpp @@ -449,19 +449,23 @@ void CodeGenFunction::EmitStartEHSpec(const Decl *D) { if (Proto == 0) return; - // FIXME: What about noexcept? - if (!Proto->hasDynamicExceptionSpec()) - return; - - unsigned NumExceptions = Proto->getNumExceptions(); - EHFilterScope *Filter = EHStack.pushFilter(NumExceptions); - - for (unsigned I = 0; I != NumExceptions; ++I) { - QualType Ty = Proto->getExceptionType(I); - QualType ExceptType = Ty.getNonReferenceType().getUnqualifiedType(); - llvm::Value *EHType = CGM.GetAddrOfRTTIDescriptor(ExceptType, - /*ForEH=*/true); - Filter->setFilter(I, EHType); + ExceptionSpecificationType EST = Proto->getExceptionSpecType(); + if (isNoexceptExceptionSpec(EST)) { + if (Proto->getNoexceptSpec(getContext()) == FunctionProtoType::NR_Nothrow) { + // noexcept functions are simple terminate scopes. + EHStack.pushTerminate(); + } + } else if (EST == EST_Dynamic || EST == EST_DynamicNone) { + unsigned NumExceptions = Proto->getNumExceptions(); + EHFilterScope *Filter = EHStack.pushFilter(NumExceptions); + + for (unsigned I = 0; I != NumExceptions; ++I) { + QualType Ty = Proto->getExceptionType(I); + QualType ExceptType = Ty.getNonReferenceType().getUnqualifiedType(); + llvm::Value *EHType = CGM.GetAddrOfRTTIDescriptor(ExceptType, + /*ForEH=*/true); + Filter->setFilter(I, EHType); + } } } @@ -476,10 +480,14 @@ void CodeGenFunction::EmitEndEHSpec(const Decl *D) { if (Proto == 0) return; - if (!Proto->hasDynamicExceptionSpec()) - return; - - EHStack.popFilter(); + ExceptionSpecificationType EST = Proto->getExceptionSpecType(); + if (isNoexceptExceptionSpec(EST)) { + if (Proto->getNoexceptSpec(getContext()) == FunctionProtoType::NR_Nothrow) { + EHStack.popTerminate(); + } + } else if (EST == EST_Dynamic || EST == EST_DynamicNone) { + EHStack.popFilter(); + } } void CodeGenFunction::EmitCXXTryStmt(const CXXTryStmt &S) { diff --git a/test/CXX/except/except.spec/p9-dynamic.cpp b/test/CXX/except/except.spec/p9-dynamic.cpp new file mode 100644 index 0000000000..3e7f931e5d --- /dev/null +++ b/test/CXX/except/except.spec/p9-dynamic.cpp @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - -fcxx-exceptions -fexceptions | FileCheck %s + +void external(); + +void target() throw(int) +{ + // CHECK: invoke void @_Z8externalv() + external(); +} +// CHECK: %eh.selector = call i32 (i8*, i8*, ...)* @llvm.eh.selector(i8* %exn, i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i32 2, i8* bitcast (i8** @_ZTIi to i8*), i8* null) nounwind +// CHECK: ehspec.unexpected: +// CHECK: call void @__cxa_call_unexpected(i8* %1) noreturn diff --git a/test/CXX/except/except.spec/p9-noexcept.cpp b/test/CXX/except/except.spec/p9-noexcept.cpp new file mode 100644 index 0000000000..71a8dee1ed --- /dev/null +++ b/test/CXX/except/except.spec/p9-noexcept.cpp @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 %s -std=c++0x -triple=x86_64-apple-darwin10 -emit-llvm -o - -fcxx-exceptions -fexceptions | FileCheck %s + +void external(); + +void target() noexcept +{ + // CHECK: invoke void @_Z8externalv() + external(); +} +// CHECK: terminate.lpad: +// CHECK: %eh.selector = call i32 (i8*, i8*, ...)* @llvm.eh.selector(i8* %exn, i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i8* null) nounwind +// CHECK-NEXT: call void @_ZSt9terminatev() noreturn nounwind +// CHECK-NEXT: unreachable + +void reverse() noexcept(false) +{ + // CHECK: call void @_Z8externalv() + external(); +}