aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/AST/ByteCode/Interp.cpp
AgeCommit message (Collapse)AuthorFilesLines
2 days[clang][bytecode][NFC] Fix a few clang-tidy complaints (#150940)Timm Baeder1-1/+1
12 days[clang][bytecode] Use bytecode interpreter in isPotentialConstantExprU… ↵Timm Baeder1-1/+8
(#149462) …nevaluated Fake a function call to the given function and evaluate the given expression as if it was part of that function call. Fixes #149383
12 days[clang][bytecode] Fix const-in-mutable fields (#149286)Timm Baeder1-1/+4
For mutable and const fields, we have two bits in InlineDescriptor, which both get inherited down the hierarchy. When a field is both const and mutable, we CAN read from it if it is a mutable-in-const field, but we _can't_ read from it if it is a const-in-mutable field. We need another bit to distinguish the two cases.
2025-07-16[clang][bytecode] Fix contains check using llvm::find (#149050)Timm Baeder1-1/+1
We need to compare to the end() interator.
2025-07-16[clang][bytecode][NFC] Remove unused function prototypes (#149031)Timm Baeder1-4/+4
2025-07-16[clang][bytecode] Make union activation more granular (#148835)Timm Baeder1-2/+5
Only activate things if the syntactical structure suggests so. This adds a bunch of new opcodes to control whether to activate in stores, etc. Fixes #134789
2025-07-11[clang][bytecode] Remove needless global check (#148163)Timm Baeder1-7/+1
Remove the call to D->hasGlobalStorage(), since we never reach this point for local variables.
2025-07-11[clang][bytecode] Keep a list of initializing blocks in InterpState (#148120)Timm Baeder1-22/+21
So we can know what blocks we're currently running constructors or destructors for.
2025-07-10[clang][bytecode] Check new/delete mismatch earlier (#147732)Timm Baeder1-14/+18
This fixes a mismatch in diagnostic output with the current intepreter.
2025-06-23[NFC][Clang][AST] Drop `llvm::` in front of `ArrayRef`/`MutableArrayRef` ↵Rahul Joshi1-1/+1
(#145207)
2025-06-20Reapply "Reapply "[clang][bytecode] Allocate IntegralAP and Floating … ↵Timm Baeder1-4/+102
(#145014) …types usi… (#144676)" This reverts commit 68471d29eed2c49f9b439e505b3f24d387d54f97. IntegralAP contains a union: union { uint64_t *Memory = nullptr; uint64_t Val; }; On 64bit systems, both Memory and Val have the same size. However, on 32 bit system, Val is 64bit and Memory only 32bit. Which means the default initializer for Memory will only zero half of Val. We fixed this by zero-initializing Val explicitly in the IntegralAP(unsigned BitWidth) constructor. See also the discussion in https://github.com/llvm/llvm-project/pull/144246
2025-06-18Revert "Reapply "[clang][bytecode] Allocate IntegralAP and Floating types ↵Timm Bäder1-102/+4
usi… (#144676)" This reverts commit 7c15edb306932e41c159f3d69c161ed0d89d47b7. This still breaks clang-armv8-quick: https://lab.llvm.org/buildbot/#/builders/154/builds/17587
2025-06-18Reapply "[clang][bytecode] Allocate IntegralAP and Floating types usi… ↵Timm Baeder1-4/+102
(#144676) …ng an allocator (#144246)" This reverts commit 57828fec760f086b334ce0cb1c465fc559dcaea4.
2025-06-17Revert "[clang][bytecode] Allocate IntegralAP and Floating types using an ↵Timm Bäder1-102/+4
allocator (#144246)" This reverts commit c66be289901b3f035187d391e80e3610d7d6232e. This breaks the armv8-quick builder: https://lab.llvm.org/buildbot/#/builders/154/builds/17549
2025-06-17[clang][bytecode] Allocate IntegralAP and Floating types using an allocator ↵Timm Baeder1-4/+102
(#144246) Both `APInt` and `APFloat` will heap-allocate memory themselves using the system allocator when the size of their data exceeds 64 bits. This is why clang has `APNumericStorage`, which allocates its memory using an allocator (via `ASTContext`) instead. Calling `getValue()` on an ast node like that will then create a new `APInt`/`APFloat` , which will copy the data (in the `APFloat` case, we even copy it twice). That's sad but whatever. In the bytecode interpreter, we have a similar problem. Large integers and floating-point values are placement-new allocated into the `InterpStack` (or into the bytecode, which is a `vector<std::byte>`). When we then later interrupt interpretation, we don't run the destructor for all items on the stack, which means we leak the memory the `APInt`/`APFloat` (which backs the `IntegralAP`/`Floating` the interpreter uses). Fix this by using an approach similar to the one used in the AST. Add an allocator to `InterpState`, which is used for temporaries and local values. Those values will be freed at the end of interpretation. For global variables, we need to promote the values to global lifetime, which we do via `InitGlobal` and `FinishInitGlobal` ops. Interestingly, this results in a slight _improvement_ in compile times: https://llvm-compile-time-tracker.com/compare.php?from=6bfcdda9b1ddf0900f82f7e30cb5e3253a791d50&to=88d1d899127b408f0fb0f385c2c58e6283195049&stat=instructions:u (but don't ask me why). Fixes https://github.com/llvm/llvm-project/issues/139012
2025-06-05[clang][bytecode] Save Constexpr bit in Function (#142793)Timm Baeder1-9/+9
Rename isConstexpr to isValid, the former was always a bad name. Save a constexpr bit in Function so we don't have to access the decl in CheckCallable.
2025-06-03[clang][bytecode] Partially address string literal uniqueness (#142555)Timm Baeder1-0/+45
This still leaves the case of the constexpr auto b3 = name1() == name1(); test from cxx20.cpp broken.
2025-05-29[clang][bytecode] Only check expr in CheckThis() if we have to (#141951)Timm Baeder1-10/+9
Pre C++11, we dont't need to get the value of IsImplicit.
2025-05-29[clang][bytecode] Simplify diagnoseUnknownDecl if we're not diagnosing (#141910)Timm Baeder1-0/+7
See the added comment. This improves compile times a bit: https://llvm-compile-time-tracker.com/compare.php?from=ac62f73f19ae9fb415d3fc423949b8d7543e8717&to=0d6cf47197a4ee11cdd1ee4a48ea38a2907c3d45&stat=instructions:u
2025-05-28[clang][bytecode] Recursively start lifetimes as well (#141742)Timm Baeder1-7/+30
The constructor starts the lifetime of all the subobjects.
2025-05-24[clang][bytecode] Check lifetime of all ptr bases in placement-new (#141272)Timm Baeder1-2/+54
placement-new'ing an object with a dead base object is not allowed, so we need to check all the pointer bases.
2025-05-23[clang][bytecode] Fix AccessKinds in placement new CheckStore() call (#141123)Timm Baeder1-1/+17
CheckStore is for assignments, but we're constructing something here, so pass AK_Construct instead. We already diagnosed the test case, but as an assignment.
2025-05-23[clang][bytecode] Diagnose placement-new'ing to a temporary (#141099)Timm Baeder1-0/+2
... that's been created in a different evaluation.
2025-05-22[clang][bytecode] Fix self-init diagnostics in C++23 (#141044)Timm Baeder1-1/+2
2025-05-22[clang][bytecode] Change diagnostics for self-initialization (#141006)Timm Baeder1-0/+15
Change the diagnostics when reading from the variable we're currently initializing do be the same as the one the current interpreter emits.
2025-05-19[clang][bytecode] Diagnose failed constexpr assertions differently (#140000)Timm Baeder1-0/+15
Adjust to the new way the ast walker is doing it.
2025-05-15[clang][bytecode] Check dtor calls for one-past-end pointers (#140047)Timm Baeder1-0/+2
2025-05-15[clang][bytecode] Check destructors for temporaries (#140039)Timm Baeder1-0/+2
Also, increase the EvalID in isPotentialConstantExpr(), since this is its own evaluation.
2025-05-13[clang][bytecode] Save Immediate bit in Function (#139671)Timm Baeder1-1/+1
Otherwise, we have to look at the FunctionDecl at every function call.
2025-05-13[clang][bytecode] Optimize enum value range checks (#139672)Timm Baeder1-3/+2
Only do the work if we really have to.
2025-05-10[clang][bytecode][NFC] Remove unused function (#139355)Timm Baeder1-9/+0
2025-05-05[clang][bytecode] Bail out on invalid function declarations (#138503)Timm Baeder1-0/+6
2025-05-01[clang][bytecode] Fix checking for integer overflow (#137962)Timm Baeder1-1/+1
We need to evaluate both the True/False expressions of a conditional operator as well as the LHS/RHS of a binary operator in more cases.
2025-04-28[clang][bytecode] Check live-ness when calling dtors (#137645)Timm Baeder1-0/+3
We can't call a destructor on a dead pointer.
2025-04-28[clang][bytecode] Don't create Function instances for builtins (#137618)Timm Baeder1-3/+3
Now that we don't use them anymore in InterpBuiltin.cpp and we don't create frames for them anymore anyway, just don't create Function instances.
2025-04-28[clang][bytecode] Don't create function frames for builtin calls (#137607)Timm Baeder1-32/+1
They don't have local variables etc. so don't create frames for them.
2025-04-28[clang][bytecode] Fix two small builtin_constant_p cases (#137587)Timm Baeder1-1/+4
Only accept string literals if we're pointing to the first index and do accept complex literals.
2025-04-27[clang][bytecode] Check for global decls in destructors (#137525)Timm Baeder1-4/+9
Destructors can't be called on global variables.
2025-04-26[clang][bytecode] Check for dummy pointers when calling pseudo dtors (#137437)Timm Baeder1-2/+1
2025-04-25[clang][bytecode] Propagate IsVolatile bit to subobjects (#137293)Timm Baeder1-10/+13
For ```c++ struct S { constexpr S(int=0) : i(1) {} int i; }; constexpr volatile S vs; ``` reading from `vs.i` is not allowed, even though `i` is not volatile qualified. Propagate the IsVolatile bit down the hierarchy, so we know reading from `vs.i` is a volatile read.
2025-04-25[clang][bytecode] Don't diagnose const extern reads in CPCE mode (#137285)Timm Baeder1-6/+8
They might become constexpr later.
2025-04-25[clang][bytecode] Allow forming pointers to fields of extern globals (#137211)Timm Baeder1-2/+0
This should be fine as long as we're not reading from it. Note that this regresses CXX/special/class.init/class.inhctor.init/p1.cpp, which used to work fine with the bytecode interpreter. That's because this code now fails: ```c++ struct Param; struct A { constexpr A(Param); int a; }; struct B : A { B(); using A::A; int b = 2; }; struct Wrap1 : B { constexpr Wrap1(); }; struct Wrap2 : Wrap1 {}; extern const Wrap2 b; struct Param { constexpr Param(int c) : n(4 * b.a + b.b + c) {} int n; }; ``` and reports that the Param() constructor is never a valid constant expression. But that's true and the current interpeter should report that as well. It also fails when calling at compile time.
2025-04-23[clang][bytecode] Refine diagnostics for volatile reads (#136857)Timm Baeder1-5/+24
Differentiate between a volarile read via a lvalue-to-rvalue cast of a volatile qualified subexpression and a read from a pointer with a volatile base object.
2025-04-18[clang][bytecode] Reject constexpr-unknown values in CheckStore (#136279)Timm Baeder1-0/+2
2025-04-16[clang][bytecode] Explicitly mark constexpr-unknown variables as such (#135806)Timm Baeder1-5/+4
Instead of trying to figure out what's constexpr-unknown later on.
2025-04-13[clang][bytecode] Reject constexpr-unknown pointers from Inc ops (#135548)Timm Baeder1-1/+1
We used to accept c++ as a known value here, causing wrong codegen.
2025-04-11[clang][bytecode] Misc TypeidPointer fixes (#135322)Timm Baeder1-1/+17
Fix comparing type id pointers, add mor info when print()ing them, use the most derived type in GetTypeidPtr() and the canonically unqualified type when we know the type statically.
2025-04-10[RFC] Initial implementation of P2719 (#113510)Oliver Hunt1-3/+7
This is a basic implementation of P2719: "Type-aware allocation and deallocation functions" described at http://wg21.link/P2719 The proposal includes some more details but the basic change in functionality is the addition of support for an additional implicit parameter in operators `new` and `delete` to act as a type tag. Tag is of type `std::type_identity<T>` where T is the concrete type being allocated. So for example, a custom type specific allocator for `int` say can be provided by the declaration of void *operator new(std::type_identity<int>, size_t, std::align_val_t); void operator delete(std::type_identity<int>, void*, size_t, std::align_val_t); However this becomes more powerful by specifying templated declarations, for example template <typename T> void *operator new(std::type_identity<T>, size_t, std::align_val_t); template <typename T> void operator delete(std::type_identity<T>, void*, size_t, std::align_val_t);); Where the operators being resolved will be the concrete type being operated over (NB. A completely unconstrained global definition as above is not recommended as it triggers many problems similar to a general override of the global operators). These type aware operators can be declared as either free functions or in class, and can be specified with or without the other implicit parameters, with overload resolution performed according to the existing standard parameter prioritisation, only with type parameterised operators having higher precedence than non-type aware operators. The only exception is destroying_delete which for reasons discussed in the paper we do not support type-aware variants by default.
2025-04-10[clang][bytecode] Classify function pointers as PT_Ptr (#135026)Timm Baeder1-7/+12
The Pointer class already has the capability to be a function pointer, but we still classifed function pointers as PT_FnPtr/FunctionPointer. This means when converting from a Pointer to a FunctionPointer, we lost the information of what the original Pointer pointed to.
2025-03-31[clang][bytecode] Reject constexpr-unknown values from comparisons (#133701)Timm Baeder1-5/+13