This allows `@TypeOf(@as([*c]T, null).*.x)` to (continue to) work.
In the long term these are probably not the semantics we want, unwrapping
a comptime-known `null` pointer should always result in `unreachable`.
Also adds missing runtime safety checks for loading null C pointers.
composite integers (wider than usize) are represented in as `[N]u32` arrays.
however, no operations were implemented before.
following operations are implemented:
- bitwise (and, or, xor, not)
- comparison (eq/neq)
- add/sub/mul/shl/shr
- `@abs`, `@intCast`
this removes 36 SPIR-V behavior test skips.
also fixed `derivePtr` to use `OpAccessChain` instead of `OpBitcast`
for array pointer casts (e.g. `*[100]u8` to `*u8`) in logical addressing
mode, where pointer bitcasts are not valid.
The SPIR-V backend previously ran codegen single-threaded in the linker thread.
Now each codegen job creates an `Mir` like other self-hosted backends.
Other changes:
- Bring back `dedup_types.zig` and `prune_unused.zig` **ISel**s which were originaly
removed because codegen was single-threaded at that time and therefor had no use
- Clean up `BinaryModule.zig`
- Remove `checkLogicalPtrOperation` from `elemPtrOneLayerOnly` in `Sema.zig`.
Element access uses `OpAccessChain`, which works on all logical address spaces
without `VariablePointers`. the check is only needed for pointer arithmetic.
Right now, when an undefined tuple value is passed to zirArrayCat, it
will call `elemValue`, which will incorrectly try to produce a undef
value of the child type (of which there is none) and then panics.
This adds a check for an undef value first to produce an undef elem
value of the correct resolved type.
Essentially `inst_map.putAssumeCapacityNoClobber` is always wrong here
because we *want* to clobber previous results when analyzing the same
switch expression multiple times.
AstGen doesn't emit a `ref` ZIR inst if it encounters a dereference `.*`
with a reference result location (`ref`/`ref_coerced_ty`/`ref_const`),
since the operand of the dereference expression already is a reference.
This caused some problems as Zig allows `.*` on both single-item *and* C
pointers, but most logic in Sema assumes that everything with a reference
rl is always a single-item pointer. This largely didn't cause any issues
since C pointers can do everything single-item pointers can, but it caused
Sema to mistake `&p.*[0]` with `@TypeOf(p) == [*c][n]T` for an index into
a many-item pointer `[*][n]T` instead of a single-item pointer `*[n]T`.
To avoid such problems in the future, a pointer obtained from `&p.*` is
now always turned into a proper single-item pointer. This is achieved by
introducing two new ZIR instructions, `deref` and `ref_deref`:
For `ptr.*`:
```
%1 = validate_deref(%ptr)
%2 = load(%ptr)
```
vvv
```
%1 = deref(%ptr)
```
For `&ptr.*`:
```
%1 = validate_deref(%ptr)
// use %ptr directly
```
vvv
```
%1 = ref_deref(%ptr)
// use %1
```
This makes `validate_deref` superfluous, so it's been removed.
Also fixes `node_offset_deref_ptr` source location to actually point to
the pointer being dereferenced and uses it to provide better source locs
for `deref` and `ref_deref`.
Identifiers like `u0_` should be legal but were previously rejected because
they were spuriously interpreted as primitive integer type identifiers.
Now the integer is first parsed and only if that succeeds it's checked for
a leading zero.
Once the switch condition is been shifted up so the minimum value is 0,
it makes sense to treat its type as the unsigned version of its original
type.
Fixes#35651
Closes#35240Fixes#35238Fixes#35259
Supported types are:
- `OpTypeSampler`
- `OpTypeImage`
- `OpTypeSampledImage`
- `OpTypeRuntimeArray` with indexing and `.len` field
The SPIR-V backend is bit-rotted so behavior tests no longer pass (compiler crashes).
However I've verified the new added tests are passing.
Previously all switch capture logic was in a single gigantic function and
had lots of weird rules around its args depending on each other which were
only encoded in doc comments and not actually enforced by the compiler.
That's odd since the 'happy path' of a switch capture is actually super
simple; it's literally just loading the switch operand inside of the scope
of the prong. Error sets introduce a little complexity since the type of
an error capture must be narrowed to the set of values that can possibly
be captured by their prong, but the real source of complexity here are
tagged union captures. First of, they support *two* captures - a payload
and a tag capture. The captured payload has to be set up correctly, and
payload captures are not guaranteed to have the same type so Sema has to
make sure that all possible payloads of a capture are compatible.
Instead of throwing all of this logic into one large function with lots of
special casing interspersed it is now split into three main paths:
- tagged unions (+ a potential tag capture)
- errors (including error set narrowing)
- everything else
This should greatly simplify reasoning about this logic in the future if
there's a bug or a change to be made. There's also no more dependencies of
args on each other; instead everything is a bit more modular, dependencies
are now encoded either as control flow or in the type system. This has
additionally lead to the OPV path being able to reuse some more of the
capture logic.
This commit also fixes inline prongs not narrowing error sets.
Since `packed` containers are now internally represented by a `bitpack`,
they need special handling on initialization: they need to be either
bitpacked or bitcasted to their backing integer. `Sema` already did this,
but `LowerZon` didn't yet.