summaryrefslogtreecommitdiff
path: root/clang/lib/CodeGen/CGExpr.cpp
AgeCommit message (Collapse)Author
2024-10-24[clang] Use {} instead of std::nullopt to initialize empty ArrayRef (#109399)Jay Foad
Follow up to #109133.
2024-10-14[clang] Fix segmentation fault caused by stack overflow on deeply nested ↵Boaz Brickner
expressions (#111701) Done by calling clang::runWithSufficientStackSpace(). Added CodeGenModule::runWithSufficientStackSpace() method similar to the one in Sema to provide a single warning when this triggers Fixes: #111699
2024-10-08[clang] Fix comment typos in CodeGen::EmitLoadOfGlobalRegLValueDavid Spickett
2024-10-07[Clang] Check that we have the correct RecordDecl (#111448)Bill Wendling
Ensure we have the correct RecordDecl before returning the Expr we're looking for.
2024-10-03[Clang] Fix 'counted_by' for nested struct pointers (#110497)Jan Hendrik Farr
Fix counted_by attribute for cases where the flexible array member is accessed through struct pointer inside another struct: ``` struct variable { int a; int b; int length; short array[] __attribute__((counted_by(length))); }; struct bucket { int a; struct variable *growable; int b; }; ``` __builtin_dynamic_object_size(p->growable->array, 0); This commit makes sure that if the StructBase is both a MemberExpr and a pointer, it is treated as a pointer. Otherwise clang will generate to code to access the address of p->growable intead of loading the value of p->growable->length. Fixes #110385
2024-10-01[HLSL] Array by-value assignment (#109323)Sarah Spall
Make Constant Arrays in HLSL assignable. Closes #109043
2024-09-27[clang][CGExpr] Avoid Type::getPointerTo() (NFC) (#110209)Youngsuk Kim
`Type::getPointerTo()` is to be removed soon. This also removes the whole code section for "C99 6.5.2.2p6"; It's essentially a no-op since llvm uses opaque pointers.
2024-09-25[clang][codegen] Don't mark "int" TBAA on FP libcalls with indirect args ↵Benjamin Maxwell
(#108853) On some targets, an FP libcall with argument types such as long double will be lowered to pass arguments indirectly via pointers. When this is the case we should not mark the libcall with "int" TBAA as it may lead to incorrect optimizations. Currently, this can be seen for long doubles on x86_64-w64-mingw32. The `load x86_fp80` after the call is (incorrectly) marked with "int" TBAA (overwriting the previous metadata for "long double"). Nothing seems to break due to this currently as the metadata is being incorrectly placed on the load and not the call. But if the metadata is moved to the call (which this patch ensures), LLVM will optimize out the setup for the arguments.
2024-09-08[Clang] C++20 Coroutines: Introduce Frontend Attribute ↵Yuxuan Chen
[[clang::coro_await_elidable]] (#99282) This patch is the frontend implementation of the coroutine elide improvement project detailed in this discourse post: https://discourse.llvm.org/t/language-extension-for-better-more-deterministic-halo-for-c-coroutines/80044 This patch proposes a C++ struct/class attribute `[[clang::coro_await_elidable]]`. This notion of await elidable task gives developers and library authors a certainty that coroutine heap elision happens in a predictable way. Originally, after we lower a coroutine to LLVM IR, CoroElide is responsible for analysis of whether an elision can happen. Take this as an example: ``` Task foo(); Task bar() { co_await foo(); } ``` For CoroElide to happen, the ramp function of `foo` must be inlined into `bar`. This inlining happens after `foo` has been split but `bar` is usually still a presplit coroutine. If `foo` is indeed a coroutine, the inlined `coro.id` intrinsics of `foo` is visible within `bar`. CoroElide then runs an analysis to figure out whether the SSA value of `coro.begin()` of `foo` gets destroyed before `bar` terminates. `Task` types are rarely simple enough for the destroy logic of the task to reference the SSA value from `coro.begin()` directly. Hence, the pass is very ineffective for even the most trivial C++ Task types. Improving CoroElide by implementing more powerful analyses is possible, however it doesn't give us the predictability when we expect elision to happen. The approach we want to take with this language extension generally originates from the philosophy that library implementations of `Task` types has the control over the structured concurrency guarantees we demand for elision to happen. That is, the lifetime for the callee's frame is shorter to that of the caller. The ``[[clang::coro_await_elidable]]`` is a class attribute which can be applied to a coroutine return type. When a coroutine function that returns such a type calls another coroutine function, the compiler performs heap allocation elision when the following conditions are all met: - callee coroutine function returns a type that is annotated with ``[[clang::coro_await_elidable]]``. - In caller coroutine, the return value of the callee is a prvalue that is immediately `co_await`ed. From the C++ perspective, it makes sense because we can ensure the lifetime of elided callee cannot exceed that of the caller if we can guarantee that the caller coroutine is never destroyed earlier than the callee coroutine. This is not generally true for any C++ programs. However, the library that implements `Task` types and executors may provide this guarantee to the compiler, providing the user with certainty that HALO will work on their programs. After this patch, when compiling coroutines that return a type with such attribute, the frontend checks that the type of the operand of `co_await` expressions (not `operator co_await`). If it's also attributed with `[[clang::coro_await_elidable]]`, the FE emits metadata on the call or invoke instruction as a hint for a later middle end pass to elide the elision. The original patch version is https://github.com/llvm/llvm-project/pull/94693 and as suggested, the patch is split into frontend and middle end solutions into stacked PRs. The middle end CoroSplit patch can be found at https://github.com/llvm/llvm-project/pull/99283 The middle end transformation that performs the elide can be found at https://github.com/llvm/llvm-project/pull/99285
2024-08-31[HLSL] Implement output parameter (#101083)Chris B
HLSL output parameters are denoted with the `inout` and `out` keywords in the function declaration. When an argument to an output parameter is constructed a temporary value is constructed for the argument. For `inout` pamameters the argument is initialized via copy-initialization from the argument lvalue expression to the parameter type. For `out` parameters the argument is not initialized before the call. In both cases on return of the function the temporary value is written back to the argument lvalue expression through an implicit assignment binary operator with casting as required. This change introduces a new HLSLOutArgExpr ast node which represents the output argument behavior. The OutArgExpr has three defined children: - An OpaqueValueExpr of the argument lvalue expression. - An OpaqueValueExpr of the copy-initialized parameter. - A BinaryOpExpr assigning the first with the value of the second. Fixes #87526 --------- Co-authored-by: Damyan Pepper <damyanp@microsoft.com> Co-authored-by: John McCall <rjmccall@gmail.com>
2024-08-23[Matrix] Preserve signedness when extending matrix index expression. (#103044)Florian Hahn
As per [1] the indices for a matrix element access operator shall have integral or unscoped enumeration types and be non-negative. At the moment, the index expression is converted to SizeType irrespective of the signedness of the index expression. This causes implicit sign conversion warnings if any of the indices is signed. As per the spec, using signed types as indices is allowed and should not cause any warnings. If the index expression is signed, extend to SignedSizeType to avoid the warning. [1] https://clang.llvm.org/docs/MatrixTypes.html#matrix-type-element-access-operator PR: https://github.com/llvm/llvm-project/pull/103044
2024-08-15[ubsan] Display correct runtime messages for negative _BitInt (#96240)earnol
Without this patch compiler-rt ubsan library has a bug displaying incorrect values for variables of the _BitInt (previously called _ExtInt) type. This patch affects affects both: generation of metadata inside code generator and runtime part. The runtime part provided only for i386 and x86_64 runtimes. Other runtimes should be updated to take full benefit of this patch. The patch is constructed the way to be backward compatible and int and float type runtime diagnostics should be unaffected for not yet updated runtimes. This patch fixes issue https://github.com/llvm/llvm-project/issues/64100. Co-authored-by: Eänolituri Lómitaurë <vladislav.aranov@ericsson.com> Co-authored-by: Aaron Ballman <aaron@aaronballman.com> Co-authored-by: Paul Kirth <paulkirth@google.com>
2024-08-15[Clang][NFC] Move FindCountedByField into FieldDecl (#104235)Bill Wendling
FindCountedByField can be used in more places than CodeGen. Move it into FieldDecl to avoid layering issues.
2024-08-09[DebugInfo][RemoveDIs] Use iterator-inserters in clang (#102006)Jeremy Morse
As part of the LLVM effort to eliminate debug-info intrinsics, we're moving to a world where only iterators should be used to insert instructions. This isn't a problem in clang when instructions get generated before any debug-info is inserted, however we're planning on deprecating and removing the instruction-pointer insertion routines. Scatter some calls to getIterator in a few places, remove a deref-then-addrof on another iterator, and add an overload for the createLoadInstBefore utility. Some callers passes a null insertion point, which we need to handle explicitly now.
2024-08-01Reapply "[Clang] Fix nomerge attribute not working with __builtin_trap(), ↵Zequan Wu
__debugbreak(), __builtin_verbose_trap() (#101549)" This reverts commit 667598d84b16d1789ce90b231565e9e7bfdbe77d and fixes failed tests: llvm/test/CodeGen/X86/nomerge.ll and llvm/test/MC/AArch64/local-bounds-single-trap.ll.
2024-08-01Revert "[Clang] Fix nomerge attribute not working with __builtin_trap(), ↵Haowei Wu
__debugbreak(), __builtin_verbose_trap() (#101549)" This reverts commit 5e84646982d1ec9bc94e48dde4b47f03c044a156, which broke 'nomerge.ll' test on llvm bots.
2024-08-01[Clang] Fix nomerge attribute not working with __builtin_trap(), ↵Zequan Wu
__debugbreak(), __builtin_verbose_trap() (#101549) 1. It fixes the problem that llvm.trap() not getting the nomerge attribute. 2. It sets nomerge flag for the node if the instruction has nomerge arrtibute. This is a copy of https://reviews.llvm.org/D146164. This only attempts to fix `nomerge` for `__builtin_trap()`, `__debugbreak()`, `__builtin_verbose_trap()`, not working for non-trap builtins. Fixes #53011
2024-08-01[Clang][NFC] Improve generation of GEP and RecordDecl loop (#101434)Bill Wendling
As with other loops, we need only look at a RecordDecl's FieldDecls. Convert to using them. In the meantime, we can improve the generation of the 'counted_by' FieldDecl's GEP by creating one GEP instead of a series of GEPs.
2024-07-23[Clang] Ignore empty FieldDecls when asking for the field number (#100040)Bill Wendling
A FieldDecl that's an empty struct may not show up in CGRecordLayout. Go ahead and ignore such a field as it shouldn't make a difference to these calculations. Fixes: 1f6f97e2b64a ("[Clang] Loop over FieldDecls instead of all Decls (#99574)") Co-authored-by: Eli Friedman <efriedma@quicinc.com>
2024-07-19[PAC] Authenticate function pointers in UBSan type checks (#99590)Akira Hatanaka
The function pointer needs to be authenticated before doing the type checks.
2024-07-18[Clang] Loop over FieldDecls instead of all Decls (#99574)Bill Wendling
Only FieldDecls are important when determining GEP indices. A struct defined within another struct has the same semantics as if it were defined outside of the struct. So there's no need to look into RecordDecls that aren't a field. See commit 5bcf31ebfad8 ("[Clang] Loop over FieldDecls instead of all Decls (#89453)") Fixes 2039.
2024-07-18[PAC] Implement function pointer re-signing (#98847)Akira Hatanaka
Re-signing occurs when function type discrimination is enabled and a function pointer is converted to another function pointer type that requires signing using a different discriminator. A function pointer is re-signed using discriminator zero when it's converted to a pointer to a non-function type such as `void*`. --------- Co-authored-by: Ahmed Bougacha <ahmed@bougacha.org> Co-authored-by: John McCall <rjmccall@apple.com>
2024-07-16[clang][CGRecordLayout] Remove dependency on isZeroSize (#96422)Michael Buch
This is a follow-up from the conversation starting at https://github.com/llvm/llvm-project/pull/93809#issuecomment-2173729801 The root problem that motivated the change are external AST sources that compute `ASTRecordLayout`s themselves instead of letting Clang compute them from the AST. One such example is LLDB using DWARF to get the definitive offsets and sizes of C++ structures. Such layouts should be considered correct (modulo buggy DWARF), but various assertions and lowering logic around the `CGRecordLayoutBuilder` relies on the AST having `[[no_unique_address]]` attached to them. This is a layout-altering attribute which is not encoded in DWARF. This causes us LLDB to trip over the various LLVM<->Clang layout consistency checks. There has been precedent for avoiding such layout-altering attributes from affecting lowering with externally-provided layouts (e.g., packed structs). This patch proposes to replace the `isZeroSize` checks in `CGRecordLayoutBuilder` (which roughly means "empty field with [[no_unique_address]]") with checks for `CodeGen::isEmptyField`/`CodeGen::isEmptyRecord`. **Details** The main strategy here was to change the `isZeroSize` check in `CGRecordLowering::accumulateFields` and `CGRecordLowering::accumulateBases` to use the `isEmptyXXX` APIs instead, preventing empty fields from being added to the `Members` and `Bases` structures. The rest of the changes fall out from here, to prevent lookups into these structures (for field numbers or base indices) from failing. Added `isEmptyRecordForLayout` and `isEmptyFieldForLayout` (open to better naming suggestions). The main difference to the existing `isEmptyRecord`/`isEmptyField` APIs, is that the `isEmptyXXXForLayout` counterparts don't have special treatment for `unnamed bitfields`/arrays and also treat fields of empty types as if they had `[[no_unique_address]]` (i.e., just like the `AsIfNoUniqueAddr` in `isEmptyField` does).
2024-07-15[clang] Use different memory layout type for _BitInt(N) in LLVM IR (#91364)Mariya Podchishchaeva
There are two problems with _BitInt prior to this patch: 1. For at least some values of N, we cannot use LLVM's iN for the type of struct elements, array elements, allocas, global variables, and so on, because the LLVM layout for that type does not match the high-level layout of _BitInt(N). Example: Currently for i128:128 targets correct implementation is possible either for __int128 or for _BitInt(129+) with lowering to iN, but not both, since we have now correct implementation of __int128 in place after a21abc7. When this happens, opaque [M x i8] types used, where M = sizeof(_BitInt(N)). 2. LLVM doesn't guarantee any particular extension behavior for integer types that aren't a multiple of 8. For this reason, all _BitInt types are now have in-memory representation that is a whole number of bytes. I.e. for example _BitInt(17) now will have memory layout type i32. This patch also introduces concept of load/store type and adds an API to CodeGenTypes that returns the IR type that should be used for load and store operations. This is particularly useful for the case when a _BitInt ends up having array of bytes as memory layout type. For _BitInt(N), let M = sizeof(_BitInt(N)), and let BITS = M * 8. Loads and stores of iM would both (1) produce far better code from the backends and (2) be far more optimizable by IR passes than loads and stores of [M x i8]. Fixes https://github.com/llvm/llvm-project/issues/85139 Fixes https://github.com/llvm/llvm-project/issues/83419 --------- Co-authored-by: John McCall <rjmccall@gmail.com>
2024-07-14[clang][NFC] Fix a warning (#98611)Piotr Fusik
enumerated and non-enumerated type in conditional expression
2024-07-05[BPF] Fix linking issues in static map initializers (#91310)Nick Zavaritsky
When BPF object files are linked with bpftool, every symbol must be accompanied by BTF info. Ensure that extern functions referenced by global variable initializers are included in BTF. The primary motivation is "static" initialization of PROG maps: ```c extern int elsewhere(struct xdp_md *); struct { __uint(type, BPF_MAP_TYPE_PROG_ARRAY); __uint(max_entries, 1); __type(key, int); __type(value, int); __array(values, int (struct xdp_md *)); } prog_map SEC(".maps") = { .values = { elsewhere } }; ``` BPF backend needs debug info to produce BTF. Debug info is not normally generated for external variables and functions. Previously, it was solved differently for variables (collecting variable declarations in ExternalDeclarations vector) and functions (logic invoked during codegen in CGExpr.cpp). This patch generalises ExternalDefclarations to include both function and variable declarations. This change ensures that function references are not missed no matter the context. Previously external functions referenced in constant expressions lacked debug info.
2024-06-26 [clang] Implement pointer authentication for C++ virtual functions, ↵Oliver Hunt
v-tables, and VTTs (#94056) Virtual function pointer entries in v-tables are signed with address discrimination in addition to declaration-based discrimination, where an integer discriminator the string hash (see `ptrauth_string_discriminator`) of the mangled name of the overridden method. This notably provides diversity based on the full signature of the overridden method, including the method name and parameter types. This patch introduces ItaniumVTableContext logic to find the original declaration of the overridden method. On AArch64, these pointers are signed using the `IA` key (the process-independent code key.) V-table pointers can be signed with either no discrimination, or a similar scheme using address and decl-based discrimination. In this case, the integer discriminator is the string hash of the mangled v-table identifier of the class that originally introduced the vtable pointer. On AArch64, these pointers are signed using the `DA` key (the process-independent data key.) Not using discrimination allows attackers to simply copy valid v-table pointers from one object to another. However, using a uniform discriminator of 0 does have positive performance and code-size implications on AArch64, and diversity for the most important v-table access pattern (virtual dispatch) is already better assured by the signing schemas used on the virtual functions. It is also known that some code in practice copies objects containing v-tables with `memcpy`, and while this is not permitted formally, it is something that may be invasive to eliminate. This is controlled by: ``` -fptrauth-vtable-pointer-type-discrimination -fptrauth-vtable-pointer-address-discrimination ``` In addition, this provides fine-grained controls in the ptrauth_vtable_pointer attribute, which allows overriding the default ptrauth schema for vtable pointers on a given class hierarchy, e.g.: ``` [[clang::ptrauth_vtable_pointer(no_authentication, no_address_discrimination, no_extra_discrimination)]] [[clang::ptrauth_vtable_pointer(default_key, default_address_discrimination, custom_discrimination, 0xf00d)]] ``` The override is then mangled as a parametrized vendor extension: ``` "__vtptrauth" I <key> <addressDiscriminated> <extraDiscriminator> E ``` To support this attribute, this patch adds a small extension to the attribute-emitter tablegen backend. Note that there are known areas where signing is either missing altogether or can be strengthened. Some will be addressed in later changes (e.g., member function pointers, some RTTI). `dynamic_cast` in particular is handled by emitting an artificial v-table pointer load (in a way that always authenticates it) before the runtime call itself, as the runtime doesn't have enough information today to properly authenticate it. Instead, the runtime is currently expected to strip the v-table pointer. --------- Co-authored-by: John McCall <rjmccall@apple.com> Co-authored-by: Ahmed Bougacha <ahmed@bougacha.org>
2024-06-21[clang] Implement function pointer signing and authenticated function calls ↵Ahmed Bougacha
(#93906) The functions are currently always signed/authenticated with zero discriminator. Co-Authored-By: John McCall <rjmccall@apple.com>
2024-06-21Revert "[ubsan] Display correct runtime messages for negative _BitInt" (#96239)earnol
Reverts llvm/llvm-project#93612 due to the issues with ppc64le platform.
2024-06-20[ubsan] Display correct runtime messages for negative _BitInt (#93612)earnol
Without this patch compiler-rt ubsan library has a bug displaying incorrect values for variables of the _BitInt (previously called _ExtInt) type. This patch affects affects both: generation of metadata inside code generator and runtime part. The runtime part provided only for i386 and x86_64 runtimes. Other runtimes should be updated to take full benefit of this patch. The patch is constructed the way to be backward compatible and int and float type runtime diagnostics should be unaffected for not yet updated runtimes. This patch fixes issue: https://github.com/llvm/llvm-project/issues/64100. Co-authored-by: Vladislav Aranov <vladislav.aranov@ericsson.com> Co-authored-by: Aaron Ballman <aaron@aaronballman.com>
2024-06-20[LLVM] Add InsertPosition union-type to remove overloads of ↵Stephen Tozer
Instruction-creation (#94226) This patch simplifies instruction creation by replacing all overloads of instruction constructors/Create methods that are identical other than the Instruction *InsertBefore/BasicBlock *InsertAtEnd/BasicBlock::iterator InsertBefore argument with a single version that takes an InsertPosition argument. The InsertPosition class can be implicitly constructed from any of the above, internally converting them to the appropriate BasicBlock::iterator value which can then be used to insert the instruction (or to not insert it if an invalid iterator is passed). The upshot of this is that code will be deduplicated, and all callsites will switch to calling the new unified version without any changes needed to make the compiler happy. There is at least one exception to this; the construction of InsertPosition is a user-defined conversion, so any caller that was already relying on a different user-defined conversion won't work. In all of LLVM and Clang this happens exactly once: at clang/lib/CodeGen/CGExpr.cpp:123 we try to construct an alloca with an AssertingVH<Instruction> argument, which must now be cast to an Instruction* by using `&*`. If this is more common elsewhere, it could be fixed by adding an appropriate constructor to InsertPosition.
2024-06-19-fsanitize=vptr: Change hash function and simplify bit mixerFangrui Song
llvm::hash_value is not guaranteed to be deterministic. Use the deterministic xxh3_64bits. A strong bit mixer isn't necessary. Use a simpler one that works well with pointers.
2024-06-17[clang][CodeGen] Return RValue from `EmitVAArg` (#94635)Mariya Podchishchaeva
This should simplify handling of resulting value by the callers.
2024-06-10[NFCI][metadata][clang] Use create{Unlikely,Likely}BranchWeights (#89467)Vitaly Buka
It does not look like particular value is inportant. Howere, there is a comment., but the current implementation of `create{Unlikely,Likely}BranchWeights` use the same value. Follow up to #89464
2024-05-23[NFC][Clang] Use `isa_and_nonnull` instead of `VD && isa<VarDecl>(VD)` (#93207)yronglin
This issue was found in https://github.com/llvm/llvm-project/pull/86960. But I'd like to avoid mixing together a bunch of cleanups with actual changes. Signed-off-by: yronglin <yronglin777@gmail.com>
2024-05-22[Clang] Remove parameter that shouldn't be there (#93086)Sirraide
The parameter of `getAddress()` was not being used, as I recall, and seems to have been removed in the meantime. Merging this w/o review since this is breaking builds.
2024-05-22[Clang] Perform derived-to-base conversion on explicit object parameter in ↵Sirraide
lambda (#89828) Consider this code: ```c++ template <typename... Ts> struct Overloaded : Ts... { using Ts::operator()...; }; template <typename... Ts> Overloaded(Ts...) -> Overloaded<Ts...>; void f() { int x; Overloaded o { [&](this auto& self) { return &x; } }; o(); } ``` To access `x` in the lambda, we need to perform derived-to-base conversion on `self` (since the type of `self` is not the lambda type, but rather `Overloaded<(lambda type)>`). We were previously missing this step, causing us to attempt to load the entire lambda (as the base class, it would end up being the ‘field’ with index `0` here), which would then assert later on in codegen. Moreover, this is only valid in the first place if there is a unique and publicly accessible cast path from the derived class to the lambda’s type, so this also adds a check in Sema to diagnose problematic cases. This fixes #87210 and fixes #89541.
2024-05-22[Clang][AArch64][SVE] Allow write to SVE vector elements using the subscript ↵Momchil Velikov
operator (#91965) The patch at https://reviews.llvm.org/D122732 introduced using the array subscript operator for SVE vectors, however it also causes an ICE when the subscripting expression is used as an lvalue. This patches fixes the error. Lvalue subscripting expressions are emitted as LLVM IR `insertelement`.
2024-05-20[clang][CodeGen] Remove unused LValue::getAddress CGF arg. (#92465)Ahmed Bougacha
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-04-29Re-apply "Emit missing cleanups for stmt-expr" and other commits (#89154)Utkarsh Saxena
Latest diff: https://github.com/llvm/llvm-project/pull/89154/files/f1ab4c2677394bbfc985d9680d5eecd7b2e6a882..adf9bc902baddb156c83ce0f8ec03c142e806d45 We address two additional bugs here: ### Problem 1: Deactivated normal cleanup still runs, leading to double-free Consider the following: ```cpp struct A { }; struct B { B(const A&); }; struct S { A a; B b; }; int AcceptS(S s); void Accept2(int x, int y); void Test() { Accept2(AcceptS({.a = A{}, .b = A{}}), ({ return; 0; })); } ``` We add cleanups as follows: 1. push dtor for field `S::a` 2. push dtor for temp `A{}` (used by ` B(const A&)` in `.b = A{}`) 3. push dtor for field `S::b` 4. Deactivate 3 `S::b`-> This pops the cleanup. 5. Deactivate 1 `S::a` -> Does not pop the cleanup as *2* is top. Should create _active flag_!! 6. push dtor for `~S()`. 7. ... It is important to deactivate **5** using active flags. Without the active flags, the `return` will fallthrough it and would run both `~S()` and dtor `S::a` leading to **double free** of `~A()`. In this patch, we unconditionally emit active flags while deactivating normal cleanups. These flags are deleted later by the `AllocaTracker` if the cleanup is not emitted. ### Problem 2: Missing cleanup for conditional lifetime extension We push 2 cleanups for lifetime-extended cleanup. The first cleanup is useful if we exit from the middle of the expression (stmt-expr/coro suspensions). This is deactivated after full-expr, and a new cleanup is pushed, extending the lifetime of the temporaries (to the scope of the reference being initialized). If this lifetime extension happens to be conditional, then we use active flags to remember whether the branch was taken and if the object was initialized. Previously, we used a **single** active flag, which was used by both cleanups. This is wrong because the first cleanup will be forced to deactivate after the full-expr and therefore this **active** flag will always be **inactive**. The dtor for the lifetime extended entity would not run as it always sees an **inactive** flag. In this patch, we solve this using two separate active flags for both cleanups. Both of them are activated if the conditional branch is taken, but only one of them is deactivated after the full-expr. --- Fixes https://github.com/llvm/llvm-project/issues/63818 Fixes https://github.com/llvm/llvm-project/issues/88478 --- Previous PR logs: 1. https://github.com/llvm/llvm-project/pull/85398 2. https://github.com/llvm/llvm-project/pull/88670 3. https://github.com/llvm/llvm-project/pull/88751 4. https://github.com/llvm/llvm-project/pull/88884
2024-04-25[NFC] Generalize ArraySections to work for OpenACC in the future (#89639)Erich Keane
OpenACC is going to need an array sections implementation that is a simpler version/more restrictive version of the OpenMP version. This patch moves `OMPArraySectionExpr` to `Expr.h` and renames it `ArraySectionExpr`, then adds an enum to choose between the two. This also fixes a couple of 'drive-by' issues that I discovered on the way, but leaves the OpenACC Sema parts reasonably unimplemented (no semantic analysis implementation), as that will be a followup patch.
2024-04-18[clang][NFC] Fix FieldDecl::isUnnamedBitfield() capitalization (#89048)Timm Baeder
We always capitalize bitfield as "BitField".
2024-04-16Revert "[codegen] Emit missing cleanups for stmt-expr and coro suspensions" ↵Utkarsh Saxena
and related commits (#88884) The original change caused widespread breakages in msan/ubsan tests and causes `use-after-free`. Most likely we are adding more cleanups than necessary.
2024-04-10[codegen] Emit missing cleanups for stmt-expr and coro suspensions [take-2] ↵Utkarsh Saxena
(#85398) Fixes https://github.com/llvm/llvm-project/issues/63818 for control flow out of an expressions. #### Background A control flow could happen in the middle of an expression due to stmt-expr and coroutine suspensions. Due to branch-in-expr, we missed running cleanups for the temporaries constructed in the expression before the branch. Previously, these cleanups were only added as `EHCleanup` during the expression and as normal expression after the full expression. Examples of such deferred cleanups include: `ParenList/InitList`: Cleanups for fields are performed by the destructor of the object being constructed. `Array init`: Cleanup for elements of an array is included in the array cleanup. `Lifetime-extended temporaries`: reference-binding temporaries in braced-init are lifetime extended to the parent scope. `Lambda capture init`: init in the lambda capture list is destroyed by the lambda object. --- #### In this PR In this PR, we change some of the `EHCleanups` cleanups to `NormalAndEHCleanups` to make sure these are emitted when we see a branch inside an expression (through statement expressions or coroutine suspensions). These are supposed to be deactivated after full expression and destroyed later as part of the destructor of the aggregate or array being constructed. To simplify deactivating cleanups, we add two utilities as well: * `DeferredDeactivationCleanupStack`: A stack to remember cleanups with deferred deactivation. * `CleanupDeactivationScope`: RAII for deactivating cleanups added to the above stack. --- #### Deactivating normal cleanups These were previously `EHCleanups` and not `Normal` and **deactivation** of **required** `Normal` cleanups had some bugs. These specifically include deactivating `Normal` cleanups which are not the top of `EHStack` [source1](https://github.com/llvm/llvm-project/blob/92b56011e6b61e7dc1628c0431ece432f282b3cb/clang/lib/CodeGen/CGCleanup.cpp#L1319), [2](https://github.com/llvm/llvm-project/blob/92b56011e6b61e7dc1628c0431ece432f282b3cb/clang/lib/CodeGen/CGCleanup.cpp#L722-L746). This has not been part of our test suite (maybe it was never required before statement expressions). In this PR, we also fix the emission of required-deactivated-normal cleanups.
2024-04-08Fix "[clang][UBSan] Add implicit conversion check for bitfields" (#87761)Axel Lundberg
Fix since #75481 got reverted. - Explicitly set BitfieldBits to 0 to avoid uninitialized field member for the integer checks: ```diff - llvm::ConstantInt::get(Builder.getInt8Ty(), Check.first)}; + llvm::ConstantInt::get(Builder.getInt8Ty(), Check.first), + llvm::ConstantInt::get(Builder.getInt32Ty(), 0)}; ``` - `Value **Previous` was erroneously `Value *Previous` in `CodeGenFunction::EmitWithOriginalRHSBitfieldAssignment`, fixed now. - Update following: ```diff - if (Kind == CK_IntegralCast) { + if (Kind == CK_IntegralCast || Kind == CK_LValueToRValue) { ``` CK_LValueToRValue when going from, e.g., char to char, and CK_IntegralCast otherwise. - Make sure that `Value *Previous = nullptr;` is initialized (see https://github.com/llvm/llvm-project/commit/1189e87951e59a81ee097eae847c06008276fef1) - Add another extensive testcase `ubsan/TestCases/ImplicitConversion/bitfield-conversion.c` --------- Co-authored-by: Vitaly Buka <vitalybuka@gmail.com>
2024-04-05[clang][CodeGen] Guard ubsan checks with `llvm.allow.ubsan.check` (#87436)Vitaly Buka
Intrinsic inserted into CodeGenFunction::EmitCheck, which is not mostly used by CFI. CFI is not the goal, and fixing inconsistencies with CFI is outside of the cope of the patch. RFC: https://discourse.llvm.org/t/rfc-add-llvm-experimental-hot-intrinsic-or-llvm-hot/77641
2024-04-03Revert "Revert "Revert "[clang][UBSan] Add implicit conversion check for ↵Vitaly Buka
bitfields""" (#87562) Reverts llvm/llvm-project#87529 Reverts #87518 https://lab.llvm.org/buildbot/#/builders/37/builds/33262 is still broken
2024-04-03Revert "Revert "[clang][UBSan] Add implicit conversion check for bitfields"" ↵Vitaly Buka
(#87529) Reverts llvm/llvm-project#87518 Revert is not needed as the regression was fixed with 1189e87951e59a81ee097eae847c06008276fef1. I assumed the crash and warning are different issues, but according to https://lab.llvm.org/buildbot/#/builders/240/builds/26629 fixing warning resolves the crash.
2024-04-03Revert "[clang][UBSan] Add implicit conversion check for bitfields" (#87518)Vitaly Buka
Reverts llvm/llvm-project#75481 Breaks multiple bots, see #75481
2024-04-03[CodeGen] Fix a warningKazu Hirata
This patch fixes: clang/lib/CodeGen/CGExpr.cpp:5607:11: error: variable 'Result' is used uninitialized whenever 'if' condition is false [-Werror,-Wsometimes-uninitialized]