This turns the current `Pointer` class into a discriminated union of
`BlockPointer` and `IntPointer`. The former is what `Pointer` currently
is while the latter is just an integer value and an optional
`Descriptor*`.
The `Pointer` then has type check functions like
`isBlockPointer()`/`isIntegralPointer()`/`asBlockPointer()`/`asIntPointer()`,
which can be used to access its data.
Right now, the `IntPointer` and `BlockPointer` structs do not have any
methods of their own and everything is instead implemented in Pointer
(like it was before) and the functions now just either assert for the
right type or decide what to do based on it.
This also implements bitcasts by decaying the pointer to an integral
pointer.
`test/AST/Interp/const-eval.c` is a new test testing all kinds of stuff
related to this. It still has a few tests `#ifdef`-ed out but that
mostly depends on other unimplemented things like
`__builtin_constant_p`.
This function tried to be smart about the dereferenced value,
but it ended up hurting more than it helped. At least in the current
state, where we still try get the correct output.
I might add something similar back later.
Just like everywhere else, we can't just abort compilation because
a function is invalid. We need to emit the Call op and let later
interpretation handle the failure.
This fixes a long standing FIXME comment.
For variadic member functions, the way we calculated the instance
pointer and RVO pointer offsts on the stack was incorrect, due
to Func->getArgSize() not returning the full size of all the
passed arguments. When calling variadic functions, we need
to pass the size of the passed (variadic) arguments to the Call*
ops, so they can use that information to properly check the
instance pointer, etc.
This patch adds a bit of code duplication in Interp.h, which I
will get rid of in later cleanup NFC patches.
Change the semantics of Pointer::isDummy() to check for a null
Pointee and returnd false in that case. Then call CheckDummy()
in ArrayElemPtr{,Pop} to protect those ops from operating on
dummy pointers and enable a few tests in test/Sema/ that now
work with the new constant interpreter.
Some time ago, I did a similar patch for local variables.
Initializing global variables can fail as well:
```c++
constexpr int a = 1/0;
static_assert(a == 0);
```
... would succeed in the new interpreter, because we never saved the
fact that `a` has not been successfully initialized.
Add an `EvaluationResult` class. This contains the result either as a
`Pointer` or as a `APValue`.
This way, we can inspect the result of the evaluation and diagnose
problems with it (e.g. uninitialized fields in global initializers or
pointers pointing to things they shouldn't point to).
This fixes a long-standing FIXME item.
Unfortunately it changes the diagnostic output of the tests added in
`cxx23.cpp`, but they were wrong before and are wrong after, so no big
deal.
We don't need to do anything here, since the input is already a Pointer.
The only complexity is that we pre-classify the parameters as PT_Ptr,
but they might end up being of a different pointer type, e.g. PT_FnPtr.
Instead of (ab)using incomplete array types for this, add a 'Dummy' bit
to Descriptor. We need to be able to differentiate between the two when
adding an offset.
Before:
```
array.cpp:319:10: note: read of uninitialized object is not allowed in a constant expression
319 | return aaa;
| ^
```
After:
```
array.cpp:319:10: note: read of uninitialized object is not allowed in a constant expression
319 | return aaa;
| ^~~
```
Rename CheckBaseDerived to something more general and call it in
GetPtrField() as well, so we don't crash later in Pointer::toAPValue().
Differential Revision: https://reviews.llvm.org/D149149
We can implement these similarly to DerivedToBase casts. We just have to
walk the class hierarchy, sum the base offsets and subtract it from the
current base offset of the pointer.
Differential Revision: https://reviews.llvm.org/D149133
The previous version was using llvm::reverse(CallExpr::arguments()),
which causes problems when clang is compiled with GCC.
Differential Revision: https://reviews.llvm.org/D155369