Age | Commit message (Collapse) | Author | Files | Lines |
|
|
|
Unused these days.
|
|
We just called `getInit()`, which isn't always correct and used the
wrong initializer in the module test case.
|
|
|
|
We only call this when we just pushed a new pointer to the stack, so try
to save the folling PopPtr op by removing the pointer inside
emitDestruction directly, e.g. by letting the Call op just remove it.
|
|
(#154286)
…rNone
|
|
Fixes #152885
|
|
(#153601)
|
|
This results in diagnostics that are closer to what the current
interpreter produces.
|
|
Sometimes we don't need the return value of a classsify() call, we only
need to know if we can map the given Expr/Type to a primitive type. Add
canClassify() for that.
|
|
|
|
Remove else after return and remove some unused includes.
|
|
The initializer itself might need the field to be active.
|
|
We use this construct a lot. Use something similar to clang's
UnsignedOrNone.
This results in some slighy compile time improvements:
https://llvm-compile-time-tracker.com/compare.php?from=17a4b0399d161a3b89d8f0ce82add1638f23f5d4&to=a251d81ecd0ed45dd190462663155fdb303ef04d&stat=instructions:u
|
|
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
|
|
When compiliung compiling a ctor or dtor, we need to devirtualize the
virtual function calls so we always call the implementation of the
current class.
|
|
We sometimes used to have a long list of
```
GetLocalPtr
PopPtr
[...]
```
ops at the end of scopes, because we first got a pointer to a local
variable and only then did we figure out that we didn't actually want to
call the destructor for it. Add a new function that allows us to just
ask the `Descriptor` whether we need to call its destructor.
|
|
(#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
|
|
usi… (#144676)"
This reverts commit 7c15edb306932e41c159f3d69c161ed0d89d47b7.
This still breaks clang-armv8-quick:
https://lab.llvm.org/buildbot/#/builders/154/builds/17587
|
|
(#144676)
…ng an allocator (#144246)"
This reverts commit 57828fec760f086b334ce0cb1c465fc559dcaea4.
|
|
allocator (#144246)"
This reverts commit c66be289901b3f035187d391e80e3610d7d6232e.
This breaks the armv8-quick builder:
https://lab.llvm.org/buildbot/#/builders/154/builds/17549
|
|
(#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
|
|
We need a place to destroy the temporaries created for call arguments.
|
|
We handle discarding fine, but we used to ignore all discarded cast
expressions. Handle bitcasts differently.
|
|
We usually call this more than once, but the type of the initializer
never changes. Let's classify only once and pass that to
visitArrayElemInit().
|
|
Emit a CCE diagnostic.
|
|
Instead of trying to figure out what's constexpr-unknown later on.
|
|
When emitting the jump for e.g. a for loop condition, we used to jump
out of the CondScope, leaving the scope initialized, because we skipped
the corresponding Destroy opcode. If that loop was in a loop itself,
that outer loop could then iterate once more, leading to us initializing
a scope that was still initialized.
Fix this by also destroying the scope after the EndLabel.
|
|
We need to recurse once more here and move the array case into the
bigger if chain.
|
|
(#130228)
This implements the R2 semantics of P0963.
The R1 semantics, as outlined in the paper, were introduced in Clang 6.
In addition to that, the paper proposes swapping the evaluation order of
condition expressions and the initialization of binding declarations
(i.e. std::tuple-like decompositions).
|
|
Use the regular code paths for interpreting.
Add new instructions: `StartSpeculation` will reset the diagnostics
pointers to `nullptr`, which will keep us from reporting any diagnostics
during speculation. `EndSpeculation` will undo this.
The rest depends on what `Emitter` we use.
For `EvalEmitter`, we have no bytecode, so we implement `speculate()` by
simply visiting the first argument of `__builtin_constant_p`. If the
evaluation fails, we push a `0` on the stack, otherwise a `1`.
For `ByteCodeEmitter`, add another instrucion called `BCP`, that
interprets all the instructions following it until the next
`EndSpeculation` instruction. If any of those instructions fails, we
jump to the `EndLabel`, which brings us right before the
`EndSpeculation`. We then push the result on the stack.
|
|
... when creating the temporary variables for a
MaterializeTemporaryExpr.
|
|
|
|
|
|
This happens e.g. when a vector element type is not primitive.
|
|
|
|
See the comment in Compiler<>::VisitCXXThisExpr.
We need to mark the InitList explicitly, so we later know what to refer
to when the init chain is active.
|
|
Add it as another kind of pointer, saving both a `Type*` for the result
of the typeid() expression as well as one for the type of the typeid
expression.
|
|
The attached test case from
https://github.com/llvm/llvm-project/issues/117294 used to cause an
assertion because we called classifPrim() on an array type.
The new result doesn't crash but isn't exactly perfect either. Since the
problem arises when evaluating an ImplicitValueInitExpr, we have no
proper source location to point to. Point to the caller instead.
|
|
This is a subset of #68288, with hopefully narrower scope. It does not
support bitcasting to non-integral types yet.
Bitfields are supported, but only if they result in a full byte-sized
final buffer. It does not support casting from null-pointers yet or
casting from indeterminate bits.
The tests are from #68288 and partially from #74775.
The `BitcastBuffer` struct is currently always working in single bits,
but I plan to (try to) optimize this for the common full-byte case.
|
|
... with non-constant initializers.
|
|
We need to use the MaterializeTemporaryExpr here so the checks in
ExprConstant.cpp do the right thing.
|
|
And some cleanups around overflow handling.
|
|
Convert the non-fixed-point side to a fixed-point type before doing the
comparison.
|
|
Add the primitive type and implement to-bool casts.
|
|
The added test case is still diagnosed differently, but I'm not sure
which version is better.
|
|
Add appropriate scopes and use reverse-order iteration in
LocalScope::emitDestructors().
|
|
(#107738)
Cleaning up _all_ the scopes is a little too much. Only clean up until
the point here we started the scope relevant for the break/continue
statement.
|
|
Reuse the __builtin_operator_{new,delete} implementations.
|
|
(#107231)
We don't need the value in this case, since we're discarding it anyway.
Allow continuing the interpretation but note the side effect.
|