aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/CodeGen/CGException.cpp
AgeCommit message (Collapse)AuthorFilesLines
2025-07-16[clang] Move `ExceptionHandling` from `LangOptions` to `CodeGenOptions` ↵Jan Svoboda1-24/+27
(#148982) This PR removes the command line parsing workaround introduced in https://github.com/llvm/llvm-project/pull/146342 by moving `LangOptions::ExceptionHandling` to `CodeGenOptions` that get parsed even for IR input. Additionally, this improves layering, where the codegen library now checks `CodeGenOptions` instead of `LangOptions` for exception handling. (This got enabled by https://github.com/llvm/llvm-project/pull/146422.)
2025-06-19[CodeGen] Use range-based for loops (NFC) (#144939)Kazu Hirata1-5/+5
2025-05-09clang: Remove dest LangAS argument from performAddrSpaceCast (#138866)Matt Arsenault1-3/+2
It isn't used and is redundant with the result pointer type argument. A more reasonable API would only have LangAS parameters, or IR parameters, not both. Not all values have a meaningful value for this. I'm also not sure why we have this at all, it's not overridden by any targets and further simplification is possible.
2025-04-03[CodeGen] Don't include CGDebugInfo.h in CodeGenFunction.h (NFC) (#134100)Nikita Popov1-0/+1
This is an expensive header, only include it where needed. Move some functions out of line to achieve that. This reduces time to build clang by ~0.5% in terms of instructions retired.
2025-03-17[clang] Change placeholder from `undef` to `poison` (#131533)Pedro Lobo1-1/+1
Return a `poison` value, instead of `undef`, if there is no available SEH info.
2025-01-24[NFC][DebugInfo] Use iterator-flavour getFirstNonPHI at many call-sites ↵Jeremy Morse1-3/+4
(#123737) As part of the "RemoveDIs" project, BasicBlock::iterator now carries a debug-info bit that's needed when getFirstNonPHI and similar feed into instruction insertion positions. Call-sites where that's necessary were updated a year ago; but to ensure some type safety however, we'd like to have all calls to getFirstNonPHI use the iterator-returning version. This patch changes a bunch of call-sites calling getFirstNonPHI to use getFirstNonPHIIt, which returns an iterator. All these call sites are where it's obviously safe to fetch the iterator then dereference it. A follow-up patch will contain less-obviously-safe changes. We'll eventually deprecate and remove the instruction-pointer getFirstNonPHI, but not before adding concise documentation of what considerations are needed (very few). --------- Co-authored-by: Stephen Tozer <Melamoto@gmail.com>
2025-01-24[NFC][DebugInfo] Use iterator moveBefore at many call-sites (#123583)Jeremy Morse1-1/+1
As part of the "RemoveDIs" project, BasicBlock::iterator now carries a debug-info bit that's needed when getFirstNonPHI and similar feed into instruction insertion positions. Call-sites where that's necessary were updated a year ago; but to ensure some type safety however, we'd like to have all calls to moveBefore use iterators. This patch adds a (guaranteed dereferenceable) iterator-taking moveBefore, and changes a bunch of call-sites where it's obviously safe to change to use it by just calling getIterator() on an instruction pointer. A follow-up patch will contain less-obviously-safe changes. We'll eventually deprecate and remove the instruction-pointer insertBefore, but not before adding concise documentation of what considerations are needed (very few).
2024-11-16[CodeGen] Remove unused includes (NFC) (#116459)Kazu Hirata1-1/+0
Identified with misc-include-cleaner.
2024-10-11[NFC] Rename `Intrinsic::getDeclaration` to `getOrInsertDeclaration` (#111752)Rahul Joshi1-2/+2
Rename the function to reflect its correct behavior and to be consistent with `Module::getOrInsertFunction`. This is also in preparation of adding a new `Intrinsic::getDeclaration` that will have behavior similar to `Module::getFunction` (i.e, just lookup, no creation).
2024-05-20[clang][CodeGen] Remove unused LValue::getAddress CGF arg. (#92465)Ahmed Bougacha1-2/+1
This is in effect a revert of f139ae3d93797, as we have since gained a more sophisticated way of doing extra IRGen with the addition of RawAddress in #86923.
2024-05-19[Clang][CodeGen] Start migrating away from assuming the Default AS is 0 (#88182)Alex Voicu1-2/+3
At the moment, Clang is rather liberal in assuming that 0 (and by extension unqualified) is always a safe default. This does not work for targets that actually use a different value for the default / generic AS (for example, the SPIRV that obtains from HIPSPV or SYCL). This patch is a first, fairly safe step towards trying to clear things up by querying a modules' default AS from the target, rather than assuming it's 0, alongside fixing a few places where things break / we encode the 0 == DefaultAS assumption. A bunch of existing tests are extended to check for non-zero default AS usage.
2024-03-28[CodeGen][arm64e] Add methods and data members to Address, which are needed ↵Akira Hatanaka1-8/+11
to authenticate signed pointers (#86923) To authenticate pointers, CodeGen needs access to the key and discriminators that were used to sign the pointer. That information is sometimes known from the context, but not always, which is why `Address` needs to hold that information. This patch adds methods and data members to `Address`, which will be needed in subsequent patches to authenticate signed pointers, and uses the newly added methods throughout CodeGen. Although this patch isn't strictly NFC as it causes CodeGen to use different code paths in some cases (e.g., `mergeAddressesInConditionalExpr`), it doesn't cause any changes in functionality as it doesn't add any information needed for authentication. In addition to the changes mentioned above, this patch introduces class `RawAddress`, which contains a pointer that we know is unsigned, and adds several new functions for creating `Address` and `LValue` objects. This reapplies d9a685a9dd589486e882b722e513ee7b8c84870c, which was reverted because it broke ubsan bots. There seems to be a bug in coroutine code-gen, which is causing EmitTypeCheck to use the wrong alignment. For now, pass alignment zero to EmitTypeCheck so that it can compute the correct alignment based on the passed type (see function EmitCXXMemberOrOperatorMemberCallExpr).
2024-03-27Revert "[CodeGen][arm64e] Add methods and data members to Address, which are ↵Akira Hatanaka1-11/+8
needed to authenticate signed pointers (#86721)" (#86898) This reverts commit d9a685a9dd589486e882b722e513ee7b8c84870c. The commit broke ubsan bots.
2024-03-27[CodeGen][arm64e] Add methods and data members to Address, which are needed ↵Akira Hatanaka1-8/+11
to authenticate signed pointers (#86721) To authenticate pointers, CodeGen needs access to the key and discriminators that were used to sign the pointer. That information is sometimes known from the context, but not always, which is why `Address` needs to hold that information. This patch adds methods and data members to `Address`, which will be needed in subsequent patches to authenticate signed pointers, and uses the newly added methods throughout CodeGen. Although this patch isn't strictly NFC as it causes CodeGen to use different code paths in some cases (e.g., `mergeAddressesInConditionalExpr`), it doesn't cause any changes in functionality as it doesn't add any information needed for authentication. In addition to the changes mentioned above, this patch introduces class `RawAddress`, which contains a pointer that we know is unsigned, and adds several new functions for creating `Address` and `LValue` objects. This reapplies 8bd1f9116aab879183f34707e6d21c7051d083b6. The commit broke msan bots because LValue::IsKnownNonNull was uninitialized.
2024-03-26Revert "[CodeGen][arm64e] Add methods and data members to Address, which are ↵Akira Hatanaka1-11/+8
needed to authenticate signed pointers (#67454)" (#86674) This reverts commit 8bd1f9116aab879183f34707e6d21c7051d083b6. It appears that the commit broke msan bots.
2024-03-25[CodeGen][arm64e] Add methods and data members to Address, which are needed ↵Akira Hatanaka1-8/+11
to authenticate signed pointers (#67454) To authenticate pointers, CodeGen needs access to the key and discriminators that were used to sign the pointer. That information is sometimes known from the context, but not always, which is why `Address` needs to hold that information. This patch adds methods and data members to `Address`, which will be needed in subsequent patches to authenticate signed pointers, and uses the newly added methods throughout CodeGen. Although this patch isn't strictly NFC as it causes CodeGen to use different code paths in some cases (e.g., `mergeAddressesInConditionalExpr`), it doesn't cause any changes in functionality as it doesn't add any information needed for authentication. In addition to the changes mentioned above, this patch introduces class `RawAddress`, which contains a pointer that we know is unsigned, and adds several new functions for creating `Address` and `LValue` objects.
2024-01-15[SystemZ][z/OS] Add support for recognizing z/OS personality function in ↵Yusra Syeda1-0/+4
Clang (#76073) This PR adds support makes Clang aware of the name of the personality function on z/OS. Co-authored-by: Yusra Syeda <yusra.syeda@ibm.com>
2024-01-10Objective C: use C++ exceptions on MinGW+GNUstep (#77255)Frederik Carlier1-2/+5
The GNUstep Objective C runtime (libobjc2) is adding support for the GNU ABI on Windows (more specifically, MinGW). The libobjc2 runtime uses C++ exceptions in that configuration; this PR updates clang to act accordingly. The corresponding change to libobjc2 is here: https://github.com/gnustep/libobjc2/pull/267
2023-12-13[clang] Use StringRef::{starts,ends}_with (NFC) (#75149)Kazu Hirata1-3/+3
This patch replaces uses of StringRef::{starts,ends}with with StringRef::{starts,ends}_with for consistency with std::{string,string_view}::{starts,ends}_with in C++20. I'm planning to deprecate and eventually remove StringRef::{starts,ends}with.
2023-11-06[clang][NFC] Refactor `ImplicitParamDecl::ImplicitParamKind`Vlad Serebrennikov1-3/+3
This patch converts `ImplicitParamDecl::ImplicitParamKind` into a scoped enum at namespace scope, making it eligible for forward declaring. This is useful for `preferred_type` annotations on bit-fields.
2023-11-04[CGException] Remove no-op ptr-to-ptr bitcasts (NFC)Youngsuk Kim1-25/+10
Opaque ptr cleanup effort (NFC).
2023-09-20[clang][CodeGen] The `eh_typeid_for` intrinsic needs special care too (#65699)Alex Voicu1-1/+7
This change is symmetric with the one reviewed in <https://reviews.llvm.org/D157452> and handles the exception handling specific intrinsic, which slipped through the cracks, in the same way, by inserting an address-space cast iff RTTI is in a non-default AS.
2023-08-30[OpenMP] Allow exceptions in target regions when offloading to GPUsAnton Rydahl1-2/+18
The motivation for this patch is that many code bases use exception handling. As GPUs are not expected to support exception handling in the near future, we can experiment with compiling the code for GPU targets anyway. This will allow us to run the code, as long as no exception is thrown. The overall idea is very simple: - If a throw expression is compiled to AMDGCN or NVPTX, it is replaced with a trap during code generation. - If a try/catch statement is compiled to AMDGCN or NVPTX, we generate code for the try statement as if it were a basic block. With this patch, the compilation of the following example ``` int gaussian_sum(int a,int b){ if ((a + b) % 2 == 0) {throw -1;}; return (a+b) * ((a+b)/2); } int main(void) { int gauss = 0; #pragma omp target map(from:gauss) { try { gauss = gaussian_sum(1,100); } catch (int e){ gauss = e; } } std::cout << "GaussianSum(1,100)="<<gauss<<std::endl; #pragma omp target map(from:gauss) { try { gauss = gaussian_sum(1,101); } catch (int e){ gauss = e; } } std::cout << "GaussianSum(1,101)="<<gauss<<std::endl; return (gauss > 1) ? 0 : 1; } ``` with offloading to `gfx906` results in ``` ./bin/target_try_minimal_fail GaussianSum(1,100)=5050 AMDGPU fatal error 1: Received error in queue 0x155555506000: HSA_STATUS_ERROR_EXCEPTION: An HSAIL operation resulted in a hardware exception. zsh: abort (core dumped) ``` Reviewed By: jdoerfert Differential Revision: https://reviews.llvm.org/D153924
2023-08-29Revert "[OpenMP] Allow exceptions in target regions when offloading to GPUs"antonrydahl1-18/+2
This reverts commit 4c62e943b7178127861ca39163a0ed4caeb14943.
2023-08-29[OpenMP] Allow exceptions in target regions when offloading to GPUsAnton Rydahl1-2/+18
The motivation for this patch is that many code bases use exception handling. As GPUs are not expected to support exception handling in the near future, we can experiment with compiling the code for GPU targets anyway. This will allow us to run the code, as long as no exception is thrown. The overall idea is very simple: - If a throw expression is compiled to AMDGCN or NVPTX, it is replaced with a trap during code generation. - If a try/catch statement is compiled to AMDGCN or AMDHSA, we ganerate code for the try statement as if it were a basic block. With this patch, the compilation of the following example ``` int gaussian_sum(int a,int b){ if ((a + b) % 2 == 0) {throw -1;}; return (a+b) * ((a+b)/2); } int main(void) { int gauss = 0; #pragma omp target map(from:gauss) { try { gauss = gaussian_sum(1,100); } catch (int e){ gauss = e; } } std::cout << "GaussianSum(1,100)="<<gauss<<std::endl; #pragma omp target map(from:gauss) { try { gauss = gaussian_sum(1,101); } catch (int e){ gauss = e; } } std::cout << "GaussianSum(1,101)="<<gauss<<std::endl; return (gauss > 1) ? 0 : 1; } ``` with offloading to `gfx906` results in ``` ./bin/target_try_minimal_fail GaussianSum(1,100)=5050 AMDGPU fatal error 1: Received error in queue 0x155555506000: HSA_STATUS_ERROR_EXCEPTION: An HSAIL operation resulted in a hardware exception. zsh: abort (core dumped) ``` Reviewed By: jdoerfert Differential Revision: https://reviews.llvm.org/D153924
2023-08-29Revert "[OpenMP] Allow exceptions in target regions when offloading to GPUs"antonrydahl1-18/+2
Reverting commit 0cfc2dba93b172802b580713a492ea14148a0218 because it broke build-bots that do not support nvptx64 targets.
2023-08-28[OpenMP] Allow exceptions in target regions when offloading to GPUsAnton Rydahl1-2/+18
The motivation for this patch is that many code bases use exception handling. As GPUs are not expected to support exception handling in the near future, we can experiment with compiling the code for GPU targets anyway. This will allow us to run the code, as long as no exception is thrown. The overall idea is very simple: - If a throw expression is compiled to AMDGCN or NVPTX, it is replaced with a trap during code generation. - If a try/catch statement is compiled to AMDGCN or AMDHSA, we ganerate code for the try statement as if it were a basic block. With this patch, the compilation of the following example ```{C++} int gaussian_sum(int a,int b){ if ((a + b) % 2 == 0) {throw -1;}; return (a+b) * ((a+b)/2); } int main(void) { int gauss = 0; #pragma omp target map(from:gauss) { try { gauss = gaussian_sum(1,100); } catch (int e){ gauss = e; } } std::cout << "GaussianSum(1,100)="<<gauss<<std::endl; #pragma omp target map(from:gauss) { try { gauss = gaussian_sum(1,101); } catch (int e){ gauss = e; } } std::cout << "GaussianSum(1,101)="<<gauss<<std::endl; return (gauss > 1) ? 0 : 1; } ``` with offloading to `gfx906` results in ```{bash} ./bin/target_try_minimal_fail GaussianSum(1,100)=5050 AMDGPU fatal error 1: Received error in queue 0x155555506000: HSA_STATUS_ERROR_EXCEPTION: An HSAIL operation resulted in a hardware exception. zsh: abort (core dumped) ``` Reviewed By: jdoerfert Differential Revision: https://reviews.llvm.org/D153924
2023-06-18[clang] Replace uses of CGBuilderTy::CreateElementBitCast (NFC)Youngsuk Kim1-1/+1
* Add `Address::withElementType()` as a replacement for `CGBuilderTy::CreateElementBitCast`. * Partial progress towards replacing `CreateElementBitCast`, as it no longer does what its name suggests. Either replace its uses with `Address::withElementType()`, or remove them if no longer needed. * Remove unused parameter 'Name' of `CreateElementBitCast` Reviewed By: barannikov88, nikic Differential Revision: https://reviews.llvm.org/D153196
2023-06-16[clang] Replace use of Type::getPointerTo() (NFC)Youngsuk Kim1-4/+2
Partial progress towards replacing in-tree uses of `Type::getPointerTo()`. This needs to be done before deprecating the API. Reviewed By: nikic, barannikov88 Differential Revision: https://reviews.llvm.org/D152321
2023-05-17Fix assertion when try is used inside catch(...) blockJennifer Yu1-1/+1
Current assert wiht /EHa: A single unwind edge may only enter one EH pad invoke void @llvm.seh.try.begin() to label %invoke.cont1 unwind label %catch.dispatch2 Current IR: %1 = catchpad within %0 [ptr null, i32 0, ptr null] invoke void @llvm.seh.try.begin() to label %invoke.cont5 unwind label %catch.dispatch2 The problem is the invoke to llvm.seh.try.begin() missing "funclet" Accodring: https://llvm.org/docs/LangRef.html#ob-funclet If any "funclet" EH pads have been entered but not exited (per the description in the EH doc), it is undefined behavior to execute a call or invoke. To fix the problem, when emit seh_try_begin, call EmitSehTryScopeBegin, instead of calling EmitRuntimeCallOrInvoke for proper "funclet" gerenration. Differential Revision: https://reviews.llvm.org/D150340
2023-02-15[CodeGen] Add a flag to `Address` and `Lvalue` that is used to keepAkira Hatanaka1-1/+1
track of whether the pointer is known not to be null The flag will be used for the arm64e work we plan to upstream in the future (see https://lists.llvm.org/pipermail/llvm-dev/2019-October/136091.html). Currently the flag has no effect on code generation. Differential Revision: https://reviews.llvm.org/D142584
2022-12-11[Clang] Use poison instead of undef where its used as placeholder [NFC]Manuel Brito1-1/+1
Differential Revision: https://reviews.llvm.org/D139745
2022-12-02Use CTAD on llvm::SaveAndRestoreJan Svoboda1-6/+3
Reviewed By: dblaikie Differential Revision: https://reviews.llvm.org/D139229
2022-11-16[clang] Fix __try/__finally blocks in C++ constructors.Eli Friedman1-2/+2
We were crashing trying to convert a GlobalDecl from a CXXConstructorDecl. Instead of trying to do that conversion, just pass down the original GlobalDecl. I think we could actually compute the correct constructor/destructor kind from the context, given the way Microsoft mangling works, but it's simpler to just pass through the correct constructor/destructor kind. Differential Revision: https://reviews.llvm.org/D136776
2022-08-08[clang] LLVM_FALLTHROUGH => [[fallthrough]]. NFCFangrui Song1-1/+1
With C++17 there is no Clang pedantic warning or MSVC C5051. Reviewed By: aaron.ballman Differential Revision: https://reviews.llvm.org/D131346
2022-03-18[CodeGen] Remove some uses of deprecated Address constructorNikita Popov1-1/+1
2022-02-17[CodeGen] Rename deprecated Address constructorNikita Popov1-2/+3
To make uses of the deprecated constructor easier to spot, and to ensure that no new uses are introduced, rename it to Address::deprecated(). While doing the rename, I've filled in element types in cases where it was relatively obvious, but we're still left with 135 calls to the deprecated constructor.
2021-12-21[CodeGen] Avoid some pointer element type accessesNikita Popov1-4/+4
This avoids some pointer element type accesses when compiling C++ code.
2021-11-10Correct handling of the 'throw()' exception specifier in C++17.James Y Knight1-9/+15
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
2021-05-20[WebAssembly] Warn on exception spec for Emscripten EHHeejin Ahn1-2/+15
It turns out we have not correctly supported exception spec all along in Emscripten EH. Emscripten EH supports `throw()` but not `throw` with types. See https://bugs.llvm.org/show_bug.cgi?id=50396. Wasm EH also only supports `throw()` but not `throw` with types, and we have been printing a warning message for the latter. This prints the same warning message for `throw` with types when Emscripten EH is used, or more precisely, when Wasm EH is not used. (So this will print the warning messsage even when `-fno-exceptions` is used but I think that should be fine. It's cumbersome to do a complilcated option checking in CGException.cpp and options checkings are mostly done in elsewhere.) Reviewed By: dschuff, kripken Differential Revision: https://reviews.llvm.org/D102791
2021-05-17[Windows SEH]: HARDWARE EXCEPTION HANDLING (MSVC -EHa) - Part 1Ten Tzen1-4/+73
This patch is the Part-1 (FE Clang) implementation of HW Exception handling. This new feature adds the support of Hardware Exception for Microsoft Windows SEH (Structured Exception Handling). This is the first step of this project; only X86_64 target is enabled in this patch. Compiler options: For clang-cl.exe, the option is -EHa, the same as MSVC. For clang.exe, the extra option is -fasync-exceptions, plus -triple x86_64-windows -fexceptions and -fcxx-exceptions as usual. NOTE:: Without the -EHa or -fasync-exceptions, this patch is a NO-DIFF change. The rules for C code: For C-code, one way (MSVC approach) to achieve SEH -EHa semantic is to follow three rules: * First, no exception can move in or out of _try region., i.e., no "potential faulty instruction can be moved across _try boundary. * Second, the order of exceptions for instructions 'directly' under a _try must be preserved (not applied to those in callees). * Finally, global states (local/global/heap variables) that can be read outside of _try region must be updated in memory (not just in register) before the subsequent exception occurs. The impact to C++ code: Although SEH is a feature for C code, -EHa does have a profound effect on C++ side. When a C++ function (in the same compilation unit with option -EHa ) is called by a SEH C function, a hardware exception occurs in C++ code can also be handled properly by an upstream SEH _try-handler or a C++ catch(...). As such, when that happens in the middle of an object's life scope, the dtor must be invoked the same way as C++ Synchronous Exception during unwinding process. Design: A natural way to achieve the rules above in LLVM today is to allow an EH edge added on memory/computation instruction (previous iload/istore idea) so that exception path is modeled in Flow graph preciously. However, tracking every single memory instruction and potential faulty instruction can create many Invokes, complicate flow graph and possibly result in negative performance impact for downstream optimization and code generation. Making all optimizations be aware of the new semantic is also substantial. This design does not intend to model exception path at instruction level. Instead, the proposed design tracks and reports EH state at BLOCK-level to reduce the complexity of flow graph and minimize the performance-impact on CPP code under -EHa option. One key element of this design is the ability to compute State number at block-level. Our algorithm is based on the following rationales: A _try scope is always a SEME (Single Entry Multiple Exits) region as jumping into a _try is not allowed. The single entry must start with a seh_try_begin() invoke with a correct State number that is the initial state of the SEME. Through control-flow, state number is propagated into all blocks. Side exits marked by seh_try_end() will unwind to parent state based on existing SEHUnwindMap[]. Note side exits can ONLY jump into parent scopes (lower state number). Thus, when a block succeeds various states from its predecessors, the lowest State triumphs others. If some exits flow to unreachable, propagation on those paths terminate, not affecting remaining blocks. For CPP code, object lifetime region is usually a SEME as SEH _try. However there is one rare exception: jumping into a lifetime that has Dtor but has no Ctor is warned, but allowed: Warning: jump bypasses variable with a non-trivial destructor In that case, the region is actually a MEME (multiple entry multiple exits). Our solution is to inject a eha_scope_begin() invoke in the side entry block to ensure a correct State. Implementation: Part-1: Clang implementation described below. Two intrinsic are created to track CPP object scopes; eha_scope_begin() and eha_scope_end(). _scope_begin() is immediately added after ctor() is called and EHStack is pushed. So it must be an invoke, not a call. With that it's also guaranteed an EH-cleanup-pad is created regardless whether there exists a call in this scope. _scope_end is added before dtor(). These two intrinsics make the computation of Block-State possible in downstream code gen pass, even in the presence of ctor/dtor inlining. Two intrinsic, seh_try_begin() and seh_try_end(), are added for C-code to mark _try boundary and to prevent from exceptions being moved across _try boundary. All memory instructions inside a _try are considered as 'volatile' to assure 2nd and 3rd rules for C-code above. This is a little sub-optimized. But it's acceptable as the amount of code directly under _try is very small. Part-2 (will be in Part-2 patch): LLVM implementation described below. For both C++ & C-code, the state of each block is computed at the same place in BE (WinEHPreparing pass) where all other EH tables/maps are calculated. In addition to _scope_begin & _scope_end, the computation of block state also rely on the existing State tracking code (UnwindMap and InvokeStateMap). For both C++ & C-code, the state of each block with potential trap instruction is marked and reported in DAG Instruction Selection pass, the same place where the state for -EHsc (synchronous exceptions) is done. If the first instruction in a reported block scope can trap, a Nop is injected before this instruction. This nop is needed to accommodate LLVM Windows EH implementation, in which the address in IPToState table is offset by +1. (note the purpose of that is to ensure the return address of a call is in the same scope as the call address. The handler for catch(...) for -EHa must handle HW exception. So it is 'adjective' flag is reset (it cannot be IsStdDotDot (0x40) that only catches C++ exceptions). Suppress push/popTerminate() scope (from noexcept/noTHrow) so that HW exceptions can be passed through. Original llvm-dev [RFC] discussions can be found in these two threads below: https://lists.llvm.org/pipermail/llvm-dev/2020-March/140541.html https://lists.llvm.org/pipermail/llvm-dev/2020-April/141338.html Differential Revision: https://reviews.llvm.org/D80344/new/
2021-05-07[SEH] Fix regression with SEH in noexpect functionsOlivier Goffart1-1/+0
Commit 5baea0560160a693b19022c5d0ba637b6b46b2d8 set the CurCodeDecl because it was needed to pass the assert in CodeGenFunction::EmitLValueForLambdaField, But this was not right to do as CodeGenFunction::FinishFunction passes it to EmitEndEHSpec and cause corruption of the EHStack. Revert the part of the commit that changes the CurCodeDecl, and instead adjust the assert to check for a null CurCodeDecl. Differential Revision: https://reviews.llvm.org/D102027
2021-03-11[CGBuilder] Remove type-less CreateAlignedLoad() APIs (NFC)Nikita Popov1-3/+4
These are incompatible with opaque pointers. This is in preparation of dropping this API on the IRBuilder side as well. Instead explicitly pass the loaded type.
2021-03-11[SEH] Fix capture of this in lambda functionsOlivier Goffart1-2/+19
Commit 1b04bdc2f3ffaa7a0e1e3dbdc3a0cd08f0b9a4ce added support for capturing the 'this' pointer in a SEH context (__finally or __except), But the case in which the 'this' pointer is part of a lambda capture was not handled properly Differential Revision: https://reviews.llvm.org/D97687
2021-03-04[WebAssembly] Disable uses of __clang_call_terminateHeejin Ahn1-10/+1
Background: Wasm EH, while using Windows EH (catchpad/cleanuppad based) IR, uses Itanium-based libraries and ABIs with some modifications. `__clang_call_terminate` is a wrapper generated in Clang's Itanium C++ ABI implementation. It contains this code, in C-style pseudocode: ``` void __clang_call_terminate(void *exn) { __cxa_begin_catch(exn); std::terminate(); } ``` So this function is a wrapper to call `__cxa_begin_catch` on the exception pointer before termination. In Itanium ABI, this function is called when another exception is thrown while processing an exception. The pointer for this second, violating exception is passed as the argument of this `__clang_call_terminate`, which calls `__cxa_begin_catch` with that pointer and calls `std::terminate` to terminate the program. The spec (https://libcxxabi.llvm.org/spec.html) for `__cxa_begin_catch` says, ``` When the personality routine encounters a termination condition, it will call __cxa_begin_catch() to mark the exception as handled and then call terminate(), which shall not return to its caller. ``` In wasm EH's Clang implementation, this function is called from cleanuppads that terminates the program, which we also call terminate pads. Cleanuppads normally don't access the thrown exception and the wasm backend converts them to `catch_all` blocks. But because we need the exception pointer in this cleanuppad, we generate `wasm.get.exception` intrinsic (which will eventually be lowered to `catch` instruction) as we do in the catchpads. But because terminate pads are cleanup pads and should run even when a foreign exception is thrown, so what we have been doing is: 1. In `WebAssemblyLateEHPrepare::ensureSingleBBTermPads()`, we make sure terminate pads are in this simple shape: ``` %exn = catch call @__clang_call_terminate(%exn) unreachable ``` 2. In `WebAssemblyHandleEHTerminatePads` pass at the end of the pipeline, we attach a `catch_all` to terminate pads, so they will be in this form: ``` %exn = catch call @__clang_call_terminate(%exn) unreachable catch_all call @std::terminate() unreachable ``` In `catch_all` part, we don't have the exception pointer, so we call `std::terminate()` directly. The reason we ran HandleEHTerminatePads at the end of the pipeline, separate from LateEHPrepare, was it was convenient to assume there was only a single `catch` part per `try` during CFGSort and CFGStackify. --- Problem: While it thinks terminate pads could have been possibly split or calls to `__clang_call_terminate` could have been duplicated, `WebAssemblyLateEHPrepare::ensureSingleBBTermPads()` assumes terminate pads contain no more than calls to `__clang_call_terminate` and `unreachable` instruction. I assumed that because in LLVM very limited forms of transformations are done to catchpads and cleanuppads to maintain the scoping structure. But it turned out to be incorrect; passes can merge cleanuppads into one, including terminate pads, as long as the new code has a correct scoping structure. One pass that does this I observed was `SimplifyCFG`, but there can be more. After this transformation, a single cleanuppad can contain any number of other instructions with the call to `__clang_call_terminate` and can span many BBs. It wouldn't be practical to duplicate all these BBs within the cleanuppad to generate the equivalent `catch_all` blocks, only with calls to `__clang_call_terminate` replaced by calls to `std::terminate`. Unless we do more complicated transformation to split those calls to `__clang_call_terminate` into a separate cleanuppad, it is tricky to solve. --- Solution (?): This CL just disables the generation and use of `__clang_call_terminate` and calls `std::terminate()` directly in its place. The possible downside of this approach can be, because the Itanium ABI intended to "mark" the violating exception handled, we don't do that anymore. What `__cxa_begin_catch` actually does is increment the exception's handler count and decrement the uncaught exception count, which in my opinion do not matter much given that we are about to terminate the program anyway. Also it does not affect info like stack traces that can be possibly shown to developers. And while we use a variant of Itanium EH ABI, we can make some deviations if we choose to; we are already different in that in the current version of the EH spec we don't support two-phase unwinding. We can possibly consider a more complicated transformation later to reenable this, but I don't think that has high priority. Changes in this CL contains: - In Clang, we don't generate a call to `wasm.get.exception()` intrinsic and `__clang_call_terminate` function in terminate pads anymore; we simply generate calls to `std::terminate()`, which is the default implementation of `CGCXXABI::emitTerminateForUnexpectedException`. - Remove `WebAssembly::ensureSingleBBTermPads() function and `WebAssemblyHandleEHTerminatePads` pass, because terminate pads are already `catch_all` now (because they don't need the exception pointer) and we don't need these transformations anymore. - Change tests to use `std::terminate` directly. Also removes tests that tested `LateEHPrepare::ensureSingleBBTermPads` and `HandleEHTerminatePads` pass. - Drive-by fix: Add some function attributes to EH intrinsic declarations Fixes https://github.com/emscripten-core/emscripten/issues/13582. Reviewed By: dschuff, tlively Differential Revision: https://reviews.llvm.org/D97834
2021-03-01[SEH] capture 'this'Olivier Goffart1-10/+15
Simply make sure that the CodeGenFunction::CXXThisValue and CXXABIThisValue are correctly initialized to the recovered value. For lambda capture, we also need to make sure to fill the LambdaCaptureFields Differential Revision: https://reviews.llvm.org/D97534
2021-01-08[WebAssembly] Rename wasm_rethrow_in_catch intrinsic/builtinHeejin Ahn1-1/+1
`wasm_rethrow_in_catch` intrinsic and builtin are used in order to rethrow an exception when the exception is caught but there is no matching clause within the current `catch`. For example, ``` try { foo(); } catch (int n) { ... } ``` If the caught exception does not correspond to C++ `int` type, it should be rethrown. These intrinsic/builtin were renamed `rethrow_in_catch` because at the time I thought there would be another intrinsic for C++'s `throw` keyword, which rethrows an exception. It turned out that `throw` keyword doesn't require wasm's `rethrow` instruction, so we rename `rethrow_in_catch` to just `rethrow` here. Reviewed By: dschuff, tlively Differential Revision: https://reviews.llvm.org/D94038
2020-12-15[clang][cli] Create accessors for exception models in LangOptionsJan Svoboda1-11/+11
This abstracts away the members that are being replaced in a follow-up patch. Depends on D83979. Reviewed By: dexonsmith Differential Revision: https://reviews.llvm.org/D93214
2020-12-02[XCOFF][AIX] Generate LSDA data and compact unwind section on AIXjasonliu1-0/+4
Summary: AIX uses the existing EH infrastructure in clang and llvm. The major differences would be 1. AIX do not have CFI instructions. 2. AIX uses a new personality routine, named __xlcxx_personality_v1. It doesn't use the GCC personality rountine, because the interoperability is not there yet on AIX. 3. AIX do not use eh_frame sections. Instead, it would use a eh_info section (compat unwind section) to store the information about personality routine and LSDA data address. Reviewed By: daltenty, hubert.reinterpretcast Differential Revision: https://reviews.llvm.org/D91455
2020-07-12[Windows SEH] Fix the frame-ptr of a nested-filter within a _finallyTen Tzen1-0/+43
This change fixed a SEH bug (exposed by test58 & test61 in MSVC test xcpt4u.c); when an Except-filter is located inside a finally, the frame-pointer generated today via intrinsic @llvm.eh.recoverfp is the frame-pointer of the immediate parent _finally, not the frame-ptr of outermost host function. The fix is to retrieve the Establisher's frame-pointer that was previously saved in parent's frame. The prolog of a filter inside a _finally should be like code below: %0 = call i8* @llvm.eh.recoverfp(i8* bitcast (@"?fin$0@0@main@@"), i8*%frame_pointer) %1 = call i8* @llvm.localrecover(i8* bitcast (@"?fin$0@0@main@@"), i8*%0, i32 0) %2 = bitcast i8* %1 to i8** %3 = load i8*, i8** %2, align 8 Differential Revision: https://reviews.llvm.org/D77982