Author: James Y Knight Date: 2021-11-10T17:40:16-05:00 New Revision: fddc4e41164e2fd152605362639eb3255cc75212
URL: https://github.com/llvm/llvm-project/commit/fddc4e41164e2fd152605362639eb3255cc75212 DIFF: https://github.com/llvm/llvm-project/commit/fddc4e41164e2fd152605362639eb3255cc75212.diff LOG: Correct handling of the 'throw()' exception specifier in C++17. Per C++17 [except.spec], 'throw()' has become equivalent to 'noexcept', and should therefore call std::terminate, not std::unexpected. Differential Revision: https://reviews.llvm.org/D113517 Added: Modified: clang/lib/CodeGen/CGException.cpp clang/test/CXX/except/except.spec/p9-dynamic.cpp Removed: ################################################################################ diff --git a/clang/lib/CodeGen/CGException.cpp b/clang/lib/CodeGen/CGException.cpp index 9f65e9eb120cf..aff9c77d53c78 100644 --- a/clang/lib/CodeGen/CGException.cpp +++ b/clang/lib/CodeGen/CGException.cpp @@ -477,11 +477,11 @@ void CodeGenFunction::EmitStartEHSpec(const Decl *D) { return; ExceptionSpecificationType EST = Proto->getExceptionSpecType(); - if (isNoexceptExceptionSpec(EST) && Proto->canThrow() == CT_Cannot) { - // noexcept functions are simple terminate scopes. - if (!getLangOpts().EHAsynch) // -EHa: HW exception still can occur - EHStack.pushTerminate(); - } else if (EST == EST_Dynamic || EST == EST_DynamicNone) { + // In C++17 and later, 'throw()' aka EST_DynamicNone is treated the same way + // as noexcept. In earlier standards, it is handled in this block, along with + // 'throw(X...)'. + if (EST == EST_Dynamic || + (EST == EST_DynamicNone && !getLangOpts().CPlusPlus17)) { // TODO: Revisit exception specifications for the MS ABI. There is a way to // encode these in an object file but MSVC doesn't do anything with it. if (getTarget().getCXXABI().isMicrosoft()) @@ -521,6 +521,10 @@ void CodeGenFunction::EmitStartEHSpec(const Decl *D) { /*ForEH=*/true); Filter->setFilter(I, EHType); } + } else if (Proto->canThrow() == CT_Cannot) { + // noexcept functions are simple terminate scopes. + if (!getLangOpts().EHAsynch) // -EHa: HW exception still can occur + EHStack.pushTerminate(); } } @@ -580,10 +584,8 @@ void CodeGenFunction::EmitEndEHSpec(const Decl *D) { return; ExceptionSpecificationType EST = Proto->getExceptionSpecType(); - if (isNoexceptExceptionSpec(EST) && Proto->canThrow() == CT_Cannot && - !EHStack.empty() /* possible empty when under async exceptions */) { - EHStack.popTerminate(); - } else if (EST == EST_Dynamic || EST == EST_DynamicNone) { + if (EST == EST_Dynamic || + (EST == EST_DynamicNone && !getLangOpts().CPlusPlus17)) { // TODO: Revisit exception specifications for the MS ABI. There is a way to // encode these in an object file but MSVC doesn't do anything with it. if (getTarget().getCXXABI().isMicrosoft()) @@ -599,6 +601,10 @@ void CodeGenFunction::EmitEndEHSpec(const Decl *D) { EHFilterScope &filterScope = cast<EHFilterScope>(*EHStack.begin()); emitFilterDispatchBlock(*this, filterScope); EHStack.popFilter(); + } else if (Proto->canThrow() == CT_Cannot && + /* possible empty when under async exceptions */ + !EHStack.empty()) { + EHStack.popTerminate(); } } diff --git a/clang/test/CXX/except/except.spec/p9-dynamic.cpp b/clang/test/CXX/except/except.spec/p9-dynamic.cpp index 1e7b29479fbdb..ccba71767729e 100644 --- a/clang/test/CXX/except/except.spec/p9-dynamic.cpp +++ b/clang/test/CXX/except/except.spec/p9-dynamic.cpp @@ -1,12 +1,26 @@ -// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - -fcxx-exceptions -fexceptions | FileCheck %s +// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - -fcxx-exceptions -fexceptions | FileCheck %s --check-prefixes=CHECK,CHECK-PRE17 +// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -std=c++17 -Wno-dynamic-exception-spec -emit-llvm -o - -fcxx-exceptions -fexceptions | FileCheck %s --check-prefixes=CHECK,CHECK-17 void external(); +// CHECK-LABEL: _Z6targetv( +// CHECK: invoke void @_Z8externalv() +// CHECK: landingpad { i8*, i32 } +// CHECK-NEXT: filter [1 x i8*] [i8* bitcast (i8** @_ZTIi to i8*)] +// CHECK: call void @__cxa_call_unexpected void target() throw(int) { - // CHECK: invoke void @_Z8externalv() external(); } -// CHECK: landingpad { i8*, i32 } -// CHECK-NEXT: filter [1 x i8*] [i8* bitcast (i8** @_ZTIi to i8*)] -// CHECK: call void @__cxa_call_unexpected + +// CHECK-LABEL: _Z7target2v( +// CHECK: invoke void @_Z8externalv() +// CHECK: landingpad { i8*, i32 } +// CHECK-PRE17-NEXT: filter [0 x i8*] zeroinitializer +// CHECK-17-NEXT: catch i8* null +// CHECK-PRE17: call void @__cxa_call_unexpected +// CHECK-17: call void @__clang_call_terminate +void target2() throw() +{ + external(); +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits