The runtime behavior allowed this in both stage1 and stage2, but stage1
fails with index out of bounds during comptime. This behavior makes
sense to support, and comptime behavior should match runtime behavior. I
implement this fix only in stage2.
My previous commit added a new behavior test that passes for stage2 but
I forgot to check whether it passes for stage1. Since it does not, it
has to be disabled.
Additionally, this commit organizes behavior tests; there is no longer a
section of tests only passing for stage1. Instead, tests are disabled on
an individual basis. There is an except for the file which has global
assembly in it.
We were enforcing bounds on the index of an elem_ptr in pointerDeref,
but we want to support out-of-bounds accesses by reinterpreting memory.
This removes that check, so that the deref falls back to bitcasting, as
usual.
This was masked by another bug that was forcing bitcasts incorrectly,
which is why this wasn't noticed earlier.
Sema.pointerDeref() assumes that elem_ptrs have been "flattened" when
they were created, so that you an elem_ptr will never be the array_ptr
of another elem_ptr when they share the same type.
Value.elemPtr does this already, but a couple of places in Sema were
bypassing this logic.
All tests have been manually verified which are now passing. This means that any remaining
TODO is an actual to-be-fixed or to-be-implemented test case.
Implements lowering constants for pointers of value 'opt_payload_ptr'.
The offset is calculated by determining the abi size of the full type and
then substracting the payload size.
Error sets contain the entire global error set.
Users are often switching on specific errors only present within that operand.
This means that cases are almost always sparse and not contiguous.
For this reason, we will instead emit the default case for error values not present in
that specific operand error set. This is fine as those cases will never be hit,
as prevented by the type system.
By still allowing jump tables for those cases, rather than if-else chains, we save runtime cost
as well as binary size.
This implements the `error_name` instruction, which is emit for runtime `@errorName` callsites.
The implementation works by creating 2 symbols and corresponding atoms.
The initial symbol contains a table which each element consisting of a slice where the ptr field
points towards the error name, and the len field contains the error name length without the sentinel.
The secondary symbol contains a list of all error names from the global error set.
During the error_name instruction, we first get a pointer to the first symbol.
Then based on the operand we perform pointer arithmetic, to get the correct index into this table.
e.g. error index 2 = ptr + (2 * ptr size). The result of this will be stored in a local
and then returned as instruction result.
During `flush()` we populate the error names table by looping over the global error set
and creating a relocation for each error name. This relocation is appended to the table symbol.
Then finally, this name is written to the names list itself.
Finally, both symbols' atom are allocated within the rest of the binary.
When no error name is referenced, the `error_name_symbol` is never set, and therefore
no error name table will be emit into the final binary.
This includes various fixes/improvements to the C backend to improve
error/union support. It also fixes up our handling of decls, where some
decls were not correctly marked alive.
This flag is used when building stage1 to omit the stage2 backends from
the compiler to save memory on the CI server. It regressed with the
merging of e8813b296bc55a13b534bd9b2a03e1f6af366915 because Value
functions started calling into Sema functions.
The end goal for this build option is to eliminate it.
This is from discussions from #11249. The stage2 behavior is correct and
is strictly more accurate, so we'd prefer to keep it. In that case, I
modified the behavior tests to have the conditional between
stage1/stage2 and get this test passing.
This commit adds a new optional argument to several Value methods which
provides the ability to resolve types if it comes to it. This prevents
having duplicated logic inside both Sema and Value.
With this commit, the "struct contains slice of itself" test is passing
by exploiting the new lazy_align Value Tag.
This reverts commit 3701697a0a586e630a2452dea29951f0051a47fd.
The commit introduced a regression when building stage2 on nixOS where
the linker would fail to find relevant LLVM dynamic libraries as some
search dirs were missing.
With this change, we can now bake in entitlements into the binary.
Additionally, I see this as the first step towards full code signature
support which includes baking in Apple issued certificates for
redistribution, etc.
Also update std/build.zig to use stage2 function pointer semantics.
This gets us a little bit closer to `zig build` working, although it is
now hitting a new crash in the compiler.
* Use `@Vector` syntax instead of `std.meta.Vector`.
* Use `var` instead of `const` for tests so that we get runtime
coverage instead of only comptime coverage. Comptime coverage is done
with `comptime doTheTest()` calls.
Made most `Value` functions require a `Type`. If the provided type is a
vector, then automatically vectorize the operation and return with
another vector. The Sema side can then automatically become vectorized
with minimal changes. There are already a few manually vectorized
instructions, but we can simplify those later.