]> granicus.if.org Git - clang/commitdiff
Reintroduce r127617: "Code generation for noexcept." with fixes.
authorSebastian Redl <sebastian.redl@getdesigned.at>
Tue, 15 Mar 2011 18:42:48 +0000 (18:42 +0000)
committerSebastian Redl <sebastian.redl@getdesigned.at>
Tue, 15 Mar 2011 18:42:48 +0000 (18:42 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@127685 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGException.cpp
test/CXX/except/except.spec/p9-dynamic.cpp [new file with mode: 0644]
test/CXX/except/except.spec/p9-noexcept.cpp [new file with mode: 0644]

index f05bc700b4ffe1b2d7750e70bd43aa8a4949938f..7fdfe700421e718424af2c96db239c9be960ec6a 100644 (file)
@@ -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 (file)
index 0000000..490d2fa
--- /dev/null
@@ -0,0 +1,11 @@
+// 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: call i32 (i8*, i8*, ...)* @llvm.eh.selector({{.*}} i8* bitcast (i8** @_ZTIi to i8*), i8* null) nounwind
+// CHECK: call void @__cxa_call_unexpected
diff --git a/test/CXX/except/except.spec/p9-noexcept.cpp b/test/CXX/except/except.spec/p9-noexcept.cpp
new file mode 100644 (file)
index 0000000..76ac66c
--- /dev/null
@@ -0,0 +1,18 @@
+// 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:  call i32 (i8*, i8*, ...)* @llvm.eh.selector({{.*}} i8* null) nounwind
+// CHECK-NEXT: call void @_ZSt9terminatev() noreturn nounwind
+// CHECK-NEXT: unreachable
+
+void reverse() noexcept(false)
+{
+  // CHECK: call void @_Z8externalv()
+  external();
+}