579 Commits

Author SHA1 Message Date
Andrew Kelley
0fcd59eada rename src/Module.zig to src/Zcu.zig
This patch is a pure rename plus only changing the file path in
`@import` sites, so it is expected to not create version control
conflicts, even when rebasing.
2024-06-22 22:59:56 -04:00
mlugg
0486aa5081
Zir: provide absolute node for reify
Since we track `reify` instructions across incremental updates, it is
acceptable to treat it as the baseline for a relative source location.
This turns out to be a good idea, since it makes it easy to define the
source location for a reified type.
2024-06-18 04:48:24 +01:00
mlugg
1eaeb4a0a8
Zcu: rework source locations
`LazySrcLoc` now stores a reference to the "base AST node" to which it
is relative. The previous tagged union is `LazySrcLoc.Offset`. To make
working with this structure convenient, `Sema.Block` contains a
convenience `src` method which takes an `Offset` and returns a
`LazySrcLoc`.

The "base node" of a source location is no longer given by a `Decl`, but
rather a `TrackedInst` representing either a `declaration`,
`struct_decl`, `union_decl`, `enum_decl`, or `opaque_decl`. This is a
more appropriate model, and removes an unnecessary responsibility from
`Decl` in preparation for the upcoming refactor which will split it into
`Nav` and `Cau`.

As a part of these `Decl` reworks, the `src_node` field is eliminated.
This change aids incremental compilation, and simplifies `Decl`. In some
cases -- particularly in backends -- the source location of a
declaration is desired. This was previously `Decl.srcLoc` and worked for
any `Decl`. Now, it is `Decl.navSrcLoc` in reference to the upcoming
refactor, since the set of `Decl`s this works for precisely corresponds
to what will in future become a `Nav` -- that is, source-level
declarations and generic function instantiations, but *not* type owner
Decls.

This commit introduces more tags to `LazySrcLoc.Offset` so as to
eliminate the concept of `error.NeededSourceLocation`. Now, `.unneeded`
should only be used to assert that an error path is unreachable. In the
future, uses of `.unneeded` can probably be replaced with `undefined`.

The `src_decl` field of `Sema.Block` no longer has a role in type
resolution. Its main remaining purpose is to handle namespacing of type
names. It will be eliminated entirely in a future commit to remove
another undue responsibility from `Decl`.

It is worth noting that in future, the `Zcu.SrcLoc` type should probably
be eliminated entirely in favour of storing `Zcu.LazySrcLoc` values.
This is because `Zcu.SrcLoc` is not valid across incremental updates,
and we want to be able to reuse error messages from previous updates
even if the source file in question changed. The error reporting logic
should instead simply resolve the location from the `LazySrcLoc` on the
fly.
2024-06-15 00:57:52 +01:00
Andrew Kelley
e89d6fc503 fix wrong int alignment for i65..i127 on x86 arch 2024-05-08 19:37:30 -07:00
Andrew Kelley
7e1cba73fc Type.intAbiAlignment: update for LLVM 18 changes
This function is intended to match what the backend desires.
No kink shaming.
2024-05-08 19:37:29 -07:00
Andrew Kelley
200e06b239 update maxIntAlignment for x86 to 16
LLVMABIAlignmentOfType(i128) reports 16 on this target, however the C
ABI uses align(4).

Clang in LLVM 17 does this:

%struct.foo = type { i32, i128 }

Clang in LLVM 18 does this:

%struct.foo = type <{ i32, i128 }>

Clang is working around the 16-byte alignment to use align(4) for the C
ABI by making the LLVM struct packed.
2024-05-08 19:37:29 -07:00
Andrew Kelley
b7799ef322 std.Target.maxIntAlignment: move to compiler implementation
This should not be a public API, and the x86 backend does not support
the value 16.
2024-05-08 19:37:29 -07:00
Andrew Kelley
65bea9ac07 LLVM 18 update: avoid passing vectors sometimes
LLVM now refuses to lower arguments and return values on x86 targets
when the total vector bit size is >= 512.

This code detects such a situation and uses byref instead of byval.
2024-05-08 19:37:28 -07:00
mlugg
d0e74ffe52
compiler: rework comptime pointer representation and access
We've got a big one here! This commit reworks how we represent pointers
in the InternPool, and rewrites the logic for loading and storing from
them at comptime.

Firstly, the pointer representation. Previously, pointers were
represented in a highly structured manner: pointers to fields, array
elements, etc, were explicitly represented. This works well for simple
cases, but is quite difficult to handle in the cases of unusual
reinterpretations, pointer casts, offsets, etc. Therefore, pointers are
now represented in a more "flat" manner. For types without well-defined
layouts -- such as comptime-only types, automatic-layout aggregates, and
so on -- we still use this "hierarchical" structure. However, for types
with well-defined layouts, we use a byte offset associated with the
pointer. This allows the comptime pointer access logic to deal with
reinterpreted pointers far more gracefully, because the "base address"
of a pointer -- for instance a `field` -- is a single value which
pointer accesses cannot exceed since the parent has undefined layout.
This strategy is also more useful to most backends -- see the updated
logic in `codegen.zig` and `codegen/llvm.zig`. For backends which do
prefer a chain of field and elements accesses for lowering pointer
values, such as SPIR-V, there is a helpful function in `Value` which
creates a strategy to derive a pointer value using ideally only field
and element accesses. This is actually more correct than the previous
logic, since it correctly handles pointer casts which, after the dust
has settled, end up referring exactly to an aggregate field or array
element.

In terms of the pointer access code, it has been rewritten from the
ground up. The old logic had become rather a mess of special cases being
added whenever bugs were hit, and was still riddled with bugs. The new
logic was written to handle the "difficult" cases correctly, the most
notable of which is restructuring of a comptime-only array (for
instance, converting a `[3][2]comptime_int` to a `[2][3]comptime_int`.
Currently, the logic for loading and storing work somewhat differently,
but a future change will likely improve the loading logic to bring it
more in line with the store strategy. As far as I can tell, the rewrite
has fixed all bugs exposed by #19414.

As a part of this, the comptime bitcast logic has also been rewritten.
Previously, bitcasts simply worked by serializing the entire value into
an in-memory buffer, then deserializing it. This strategy has two key
weaknesses: pointers, and undefined values. Representations of these
values at comptime cannot be easily serialized/deserialized whilst
preserving data, which means many bitcasts would become runtime-known if
pointers were involved, or would turn `undefined` values into `0xAA`.
The new logic works by "flattening" the datastructure to be cast into a
sequence of bit-packed atomic values, and then "unflattening" it; using
serialization when necessary, but with special handling for `undefined`
values and for pointers which align in virtual memory. The resulting
code is definitely slower -- more on this later -- but it is correct.

The pointer access and bitcast logic required some helper functions and
types which are not generally useful elsewhere, so I opted to split them
into separate files `Sema/comptime_ptr_access.zig` and
`Sema/bitcast.zig`, with simple re-exports in `Sema.zig` for their small
public APIs.

Whilst working on this branch, I caught various unrelated bugs with
transitive Sema errors, and with the handling of `undefined` values.
These bugs have been fixed, and corresponding behavior test added.

In terms of performance, I do anticipate that this commit will regress
performance somewhat, because the new pointer access and bitcast logic
is necessarily more complex. I have not yet taken performance
measurements, but will do shortly, and post the results in this PR. If
the performance regression is severe, I will do work to to optimize the
new logic before merge.

Resolves: #19452
Resolves: #19460
2024-04-17 13:41:25 +01:00
Jacob Young
7611d90ba0 InternPool: remove slice from byte aggregate keys
This deletes a ton of lookups and avoids many UAF bugs.

Closes #19485
2024-04-08 13:24:08 -04:00
Jacob Young
5a41704f7e cbe: rewrite CType
Closes #14904
2024-03-30 20:50:48 -04:00
mlugg
2a245e3b78
compiler: eliminate TypedValue
The only logic which remained in this file was the Value printing logic.
This has been moved into a new `print_value.zig`.
2024-03-26 13:48:07 +00:00
mlugg
a61def10c6
compiler: eliminate most usages of TypedValue 2024-03-26 13:48:07 +00:00
mlugg
884d957b6c
compiler: eliminate legacy Value representation
Good riddance!

Most of these changes are trivial. There's a fix for a minor bug this
exposed in `Value.readFromPackedMemory`, but aside from that, it's all
just things like changing `intern` calls to `toIntern`.
2024-03-26 13:48:06 +00:00
Andrew Kelley
95cb939440
Merge pull request #19333 from Vexu/fixes
Miscellaneous error fixes
2024-03-17 15:26:55 -07:00
Veikka Tuominen
fec4b7ef5c Sema: fix spurious type has no namespace error
Closes #19232
2024-03-17 14:42:12 +02:00
Veikka Tuominen
f983adfc10 Sema: fix printing of inferred error set of generic fn
Closes #19332
2024-03-17 13:33:05 +02:00
Jacob Young
d10c52c194 AstGen: disallow alignment on function types
A pointer type already has an alignment, so this information does not
need to be duplicated on the function type.  This already has precedence
with addrspace which is already disallowed on function types for this
reason.  Also fixes `@TypeOf(&func)` to have the correct addrspace and
alignment.
2024-03-17 03:06:17 +01:00
Tristan Ross
099f3c4039
std.builtin: make container layout fields lowercase 2024-03-11 07:09:07 -07:00
mlugg
d0c022f734
compiler: namespace type equivalence based on AST node + captures
This implements the accepted proposal #18816. Namespace-owning types
(struct, enum, union, opaque) are no longer unique whenever analysed;
instead, their identity is determined based on their AST node and the
set of values they capture.

Reified types (`@Type`) are deduplicated based on the structure of the
type created. For instance, if two structs are created by the same
reification with identical fields, layout, etc, they will be the same
type.

This commit does not produce a working compiler; the next commit, adding
captures for decl references, is necessary. It felt appropriate to split
this up.

Resolves: #18816
2024-03-06 21:26:37 +00:00
mlugg
8ec6f730ef
compiler: represent captures directly in InternPool
These were previously associated with the type's namespace, but we need
to store them directly in the InternPool for #18816.
2024-03-06 21:26:37 +00:00
mlugg
975b859377
InternPool: create specialized functions for loading namespace types
Namespace types (`struct`, `enum`, `union`, `opaque`) do not use
structural equality - equivalence is based on their Decl index (and soon
will change to AST node + captures). However, we previously stored all
other information in the corresponding `InternPool.Key` anyway. For
logical consistency, it makes sense to have the key only be the true key
(that is, the Decl index) and to load all other data through another
function. This introduces those functions, by the name of
`loadStructType` etc. It's a big diff, but most of it is no-brainer
changes.

In future, it might be nice to eliminate a bunch of the loaded state in
favour of accessor functions on the `LoadedXyzType` types (like how we
have `LoadedUnionType.size()`), but that can be explored at a later
date.
2024-03-06 21:26:37 +00:00
John Schmidt
f803761e13 Fix tuple default values
- Add default values to the list of comptime-known elements in
  `zirValidatePtrArrayInit`
- In `structFieldValueComptime`, only assert `haveFieldInits` if we
  enter the`fieldIsComptime` branch (otherwise they are not needed).
2024-02-26 17:03:20 -08:00
Jacob Young
a76d8ca29b x86_64: fix alignment of bool vectors 2024-02-25 11:22:10 +01:00
Jacob Young
2fcb2f5975 Sema: implement vector coercions
These used to be lowered elementwise in air, and now are a single air
instruction that can be lowered elementwise in the backend if necessary.
2024-02-25 11:22:10 +01:00
Jacob Young
2fdc9e6ae8 x86_64: implement @shuffle 2024-02-25 11:22:10 +01:00
Jacob Young
6f08e17229 InternPool: make more use of NullTerminatedString.Slice
This should avoid the random pointer invalidation crashes.

Closes #18954
2024-02-16 00:27:25 -08:00
Veikka Tuominen
51d67c7c8f Sema: add declared here notes in fail
This ensures that the note is added in more places and that `errMsg` needs to be used in fewer places.
2024-02-12 12:54:32 -08:00
Matthew Lugg
0c80725068
Merge pull request #18814 from mlugg/incremental-dependencies
Begin re-implementing incremental compilation
2024-02-06 11:33:07 +00:00
Andrew Kelley
78f15bc714 compiler: rename value.zig to Value.zig
This commit only does the file rename to be friendlier to version
control conflicts.
2024-02-05 18:13:07 -07:00
mlugg
7f4bd247c7
compiler: re-introduce dependencies for incremental compilation
Sema now tracks dependencies appropriately. Early logic in Zcu for
resolving outdated decls/functions is in place. The setup used does not
support `usingnamespace`; compilations using this construct are not yet
supported by this incremental compilation model.
2024-02-04 18:38:39 +00:00
mlugg
9eda6ccefc InternPool: use separate key for slices
This change eliminates some problematic recursive logic in InternPool,
and provides a safer API.
2024-02-02 11:02:03 +00:00
SuperAuguste
a479fd3132 Fix some comptime packed struct issues
Co-authored-by: Veikka Tuominen <git@vexu.eu>
2024-01-29 13:09:17 -08:00
Veikka Tuominen
2e7d28dd0d Sema: replace uses of toUnsignedInt with toUnsignedIntAdvanced
During semantic analysis the value may be an unresolved lazy value
which makes using `toUnsignedInt` invalid.

Add assertions to detect similar issues in the future.

Closes #18624
2024-01-20 12:21:05 -08:00
Meghan Denny
2549de80b2 move Module.Decl.Index and Module.Namespace.Index to InternPool 2023-11-26 02:24:40 -05:00
Techatrix
18608223ef convert toType and toValue to Type.fromInterned and Value.fromInterned 2023-11-25 04:09:53 -05:00
kcbanner
3fc6a2f113 sema: pass sema through if available for the array_type case in bitSizeAdvanced 2023-11-11 13:11:51 +00:00
kcbanner
f10499be0a
sema: analyze field init bodies in a second pass
This change allows struct field inits to use layout information
of their own struct without causing a circular dependency.

`semaStructFields` caches the ranges of the init bodies in the `StructType`
trailing data. The init bodies are then resolved by `resolveStructFieldInits`,
which is called before the inits are actually required.

Within the init bodies, the struct decl's instruction is repurposed to refer
to the field type itself. This is to allow us to easily rebuild the inst_map
mapping required for the init body instructions to refer to the field type.

Thanks to @mlugg for the guidance on this one!
2023-11-07 00:49:35 +00:00
kcbanner
4d044ee7e0 sema: Add union alignment resolution
- Add resolveUnionAlignment, to resolve a union's alignment only, without triggering layout resolution.
- Update resolveUnionLayout to cache size, alignment, and padding. abiSizeAdvanced and abiAlignmentAdvanced
  now use this information instead of computing it each time.
2023-10-31 01:35:58 +00:00
DilithiumNitrate
91e117697a
Fix hasRuntimeBitsAdvanced lazy case for pointers and optionals
As suggested by mlugg, always returns `error.NeedLazy`. If this has a
performance impact, it could be replaced by adding lazy handling to
`comptimeOnlyAdvanced`.
2023-10-29 21:12:43 +00:00
mlugg
20bb81166f
InternPool: remove runtime_value representation
The main goal of this commit is to remove the `runtime_value` field from
`InternPool.Key` (and its associated representation), but there are a
few dominos. Specifically, this mostly eliminates the "maybe runtime"
concept from value resolution in Sema: so some resolution functions like
`resolveMaybeUndefValAllowVariablesMaybeRuntime` are gone. This required
a small change to struct/union/array initializers, to no longer
use `runtime_value` if a field was a `variable` - I'm not convinced this
case was even reachable, as `variable` should only ever exist as the
trivial value of a global runtime `var` decl.

Now, the only case in which a `Sema.resolveMaybeUndefVal`-esque function
can return the `variable` key is `resolveMaybeUndefValAllowVariables`,
which is directly called from `Sema.resolveInstValueAllowVariables`
(previously `Sema.resolveInstValue`), which is only used for resolving
the value of a Decl from `Module.semaDecl`.

While changing these functions, I also slightly reordered and
restructured some of them, and updated their doc comments.
2023-10-24 14:28:33 +01:00
Veikka Tuominen
9d9e22e716 remove uses of non-configurable err_int 2023-10-22 14:29:26 +03:00
Veikka Tuominen
bf61c5c065 make distinct error limit configurable
Closes #786
2023-10-21 12:36:29 +03:00
Andrew Kelley
328ec15d9c Revert "make distinct error limit configurable"
This reverts commit 78855bd21866b515018259a2194e036e4b3120df.

This commit did not replace uses of `Type.err_int` of which there are
currently 60 uses.

Re-opens #786
2023-10-20 14:03:55 -07:00
Veikka Tuominen
78855bd218 make distinct error limit configurable
Closes #786
2023-10-16 04:08:45 -04:00
mlugg
1033d71017 Sema,type: unify type query functions
The following pairs of functions have been combined using the "advanced"
pattern used for other type queries:

* `Sema.fnHasRuntimeBits`, `Type.isFnOrHasRuntimeBits`
* `Sema.typeRequiresComptime`, `Type.comptimeOnly`
2023-10-10 21:40:23 -07:00
Andrew Kelley
87d09edf2d
Merge pull request #17352 from kcbanner/extern_union_comptime_memory
sema: Support reinterpreting extern/packed unions at comptime via field access
2023-10-03 11:20:08 -07:00
Xavier Bouchoux
405705cb76 codegen: fix byte-aligned field offsets in unaligned nested packed structs 2023-10-03 05:34:19 +00:00
Xavier Bouchoux
62d178e91a codegen: fix field offsets in packed structs
* add nested packed struct/union behavior tests
 * use ptr_info.packed_offset rather than trying to duplicate the logic from Sema.structFieldPtrByIndex()
 * use the container_ptr_info.packed_offset to account for non-aligned nested structs.
 * dedup type.packedStructFieldBitOffset() and module.structPackedFieldBitOffset()
2023-10-03 06:39:20 +02:00
kcbanner
d657b6c0e2 sema: support reinterpreting extern/packed unions at comptime via field access
My previous change for reading / writing to unions at comptime did not handle
union field read/writes correctly in all cases. Previously, if a field was
written to a union, it would overwrite the entire value. This is problematic
when a field of a larger size is subsequently read, because the value would not
be long enough, causing a panic.

Additionally, the writing behaviour itself was incorrect. Writing to a field of
a packed or extern union should only overwrite the bits corresponding to that
field, allowing for memory reintepretation via field writes / reads.

I addressed these problems as follows:

Add the concept of a "backing type" for extern / packed unions
(`Type.unionBackingType`).  For extern unions, this is a `u8` array, for packed
unions it's an integer matching the `bitSize` of the union. Whenever union
memory is read at comptime, it's read as this type.

When union memory is written at comptime, the tag may still be known. If so, the
memory is written using the tagged type. If the tag is unknown (because this
union had previously been read from memory), it's simply written back out as the
backing type.

I added `write_packed` to the `reinterpret` field of
`ComptimePtrMutationKit`. This causes writes of the operand to be packed - which
is necessary when writing to a field of a packed union. Without this, writing a
value to a `u1` field would overwrite the entire byte it occupied.

The final case to address was reading a different (potentially larger) field
from a union when it was written with a known tag. To handle this, a new kind of
bitcast was introduced (`bitCastUnionFieldVal`) which supports reading a larger
field by using a backing buffer that has the unwritten bits set to
undefined. The reason to support this (vs always just writing the union as it's
backing type), is that no reads to larger fields ever occur at comptime, it
would be strictly worse to have spent time writing the full backing type.
2023-10-02 13:15:28 -04:00