363 Commits

Author SHA1 Message Date
Robin Voetter
1d33822020 stage2: forbid double dereference in Sema.elemVal 2021-10-21 16:24:18 +02:00
Andrew Kelley
a0e195120d stage2: implement slicing
* New AIR instruction: slice, which constructs a slice out of a pointer
   and a length.
 * AstGen: use `coerced_ty` for start and end expressions, use `none`
   for the sentinel, and don't try to load the result of the slice
   operation because it returns a by-value result.
 * Sema: pointer arithmetic is extracted into analyzePointerArithmetic
   and it is used by the implementation of slice.
   - Also I implemented comptime pointer addition.
 * Sema: extract logic into analyzeSlicePtr, analyzeSliceLen and use them
   inside the slice semantic analysis.
   - The approach in stage2 is much cleaner than stage1 because it uses
     more granular analysis calls for obtaining the slice pointer, doing
     arithmetic on it, and checking if the length is comptime-known.
 * Sema: use the slice Value Tag for slices when doing coercion from
   pointer-to-array.
 * LLVM backend: detect when emitting a GEP instruction into a
   pointer-to-array and add the extra index that is required.
 * Type: ptrAlignment for c_void returns 0.
 * Implement Value.hash and Value.eql for slices.
 * Remove accidentally duplicated behavior test.
2021-10-20 21:45:11 -07:00
Andrew Kelley
3b2e25ed87 Sema: fix missing copy in array multiplication
lead to a Use-After-Free in backend codgen
2021-10-20 17:02:15 -07:00
Andrew Kelley
dfb3231959 stage2: implement switching on unions
* AstGen: Move `refToIndex` and `indexToRef` to Zir
 * ZIR: the switch_block_*_* instruction tags are collapsed into one
   switch_block tag which uses 4 bits for flags, and reduces the
   scalar_cases_len field from 32 to 28 bits.
   This freed up more ZIR tags, 2 of which are now used for
   `switch_cond` and `switch_cond_ref` for producing the switch
   condition value. For example, for union values it returns the
   corresponding enum value.
 * switching with multiple cases and ranges is not yet supported because
   I want to change the ZIR encoding to store index pointers into the
   extra array rather than storing prong indexes. This will avoid O(N^2)
   iteration over prongs.
 * AstGen now adds a `switch_cond` on the operand and then passes the
   result of that to the `switch_block` instruction.
 * Sema: partially implement `switch_capture_*` instructions.
 * Sema: `unionToTag` notices if the enum type has only one possible value.
2021-10-19 20:22:47 -07:00
Andrew Kelley
c1508c98f4 stage2 minor cleanups 2021-10-19 19:38:43 -07:00
Andrew Kelley
e4c437f23b stage2: implement union member access as enum tag 2021-10-19 19:03:20 -07:00
Robin Voetter
6329f4e47a stage2: union field value 2021-10-20 03:44:02 +02:00
Robin Voetter
d6f048c456 stage2: make (typeHas)OnePossibleValue return the right value 2021-10-20 03:44:02 +02:00
Robin Voetter
bfedf40c92 stage2: zirIndexablePtrLen for non-pointer types 2021-10-20 03:44:02 +02:00
Robin Voetter
c507e0b763 stage2: Sema.fieldPtr for slice ptr and len 2021-10-20 03:44:02 +02:00
Robin Voetter
e5d6fe18b9 stage2: restructure Sema.fieldVal and sema.fieldPtr
Dereferencing single pointers is now handled outside of the main switch,
which allows deduplication of some cases. This also implements the
relevant operations for pointers to types and pointers to slices.
2021-10-20 03:44:02 +02:00
Andrew Kelley
bea447a637 stage2: fix coercion of error set to error union
When returning an error set or an error union from a function which has
an inferred error set, it populates the error names in addition to the
set of functions. This can have false negatives, meaning that after
checking the map of an unresolved error set, one must do full error set
resolution before emitting a compile error.
2021-10-18 15:45:11 -07:00
Andrew Kelley
7b00bef6bf Sema: resolveTypeFields before accessing type fields 2021-10-17 21:53:59 -07:00
Meghan Denny
0ef2e2520a stage2: implement @hasField
struct and union are kept in stage1 because struct/unionFieldCount are returning zero
2021-10-17 21:42:22 -07:00
Andrew Kelley
40cbf525f7 stage2: implement coercion from null to C pointer 2021-10-17 19:10:49 -07:00
Andrew Kelley
e5dac0a0b3 stage2: implement @embedFile 2021-10-17 18:59:11 -07:00
Andrew Kelley
ad17108bdd
Merge pull request #9960 from Snektron/bit-not
Some not and vector stuff
2021-10-17 21:59:10 -04:00
Andrew Kelley
6534f2ef4f stage2: implement error wrapping
* Sema: fix returned operands not coercing to the function return type
   in some cases.
   - When returning an error or an error union from a function with an
     inferred error set, it will now populate the inferred error set.
   - Implement error set coercion for the common case of inferred error
     set to inferred error set, without forcing a full resolution.
 * LLVM backend: update instruction lowering that handles error unions
   to respect `isByRef`.
   - Also implement `wrap_err_union_err`.
2021-10-17 14:55:32 -07:00
Robin Voetter
d004ef2e5d stage2: make zirBoolNot return undefined when argument is undefined 2021-10-17 20:33:04 +02:00
Robin Voetter
d193ba9843 stage2: array->vector coercion 2021-10-17 20:33:04 +02:00
Robin Voetter
9336a87452 stage2: bitNot 2021-10-17 20:33:04 +02:00
Andrew Kelley
fdd11f6cee Sema: coercion from error sets to anyerror 2021-10-16 12:41:03 -07:00
Andrew Kelley
4d6d6977b0 stage2: fixes to extern variables
* Relax compile error for "unable to export type foo" to allow
   integers, structs, arrays, and floats. This will need to be further
   improved to do the same checks as we do for C ABI struct field types.
 * LLVM backend: fix extern variables
 * LLVM backend: implement AIR instruction `wrap_err_union_payload`
2021-10-16 12:26:06 -07:00
Robin Voetter
f6bf24b2f3 stage2: comptime saturating shl 2021-10-16 11:32:05 +02:00
Andrew Kelley
682cdeceaa stage2: optional comparison and 0-bit payloads
* Sema: implement peer type resolution for optionals and null.
 * Rename `Module.optionalType` to `Type.optional`.
 * LLVM backend: re-use anonymous values. This is especially useful when
   isByRef()=true because it means re-using the same generated LLVM globals.
 * LLVM backend: rework the implementation of is_null and is_non_null
   AIR instructions. Generate slightly better LLVM code, and also fix
   the behavior for optionals whose payload type is 0-bit.
 * LLVM backend: improve `cmp` AIR instruction lowering to support
   pointer-like optionals.
 * `Value`: implement support for equality-checking optionals.
2021-10-15 18:37:09 -07:00
Andrew Kelley
55eea3b045 stage2: implement @minimum and @maximum, including vectors
* std.os: take advantage of `@minimum`. It's probably time to
   deprecate `std.min` and `std.max`.
 * New AIR instructions: min and max
 * Introduce SIMD vector support to stage2
 * Add `@Type` support for vectors
 * Sema: add `checkSimdBinOp` which can be re-used for other arithmatic
   operators that want to support vectors.
 * Implement coercion from vectors to arrays.
   - In backends this is handled with bitcast for vector to array,
     however maybe we want to reduce the amount of branching by
     introducing an explicit AIR instruction for it in the future.
 * LLVM backend: implement lowering vector types
 * Sema: Implement `slice.ptr` at comptime
 * Value: improve `numberMin` and `numberMax` to support floats in
   addition to integers, and make them behave properly in the presence
   of NaN.
2021-10-14 21:17:30 -07:00
Andrew Kelley
8b88274781 stage2: improved union support
* `Module.Union.getFullyQualifiedName` returns a sentinel-terminated
   slice so that backends that need null-termination do not need an
   additional copy.
 * Module.Union: implement a `getLayout` function which returns
   information about ABI size and alignment so that the LLVM backend can
   properly lower union types into llvm types.
 * Sema: `resolveType` now returns `error.GenericPoison` rather than a
   Type with tag `generic_poison`. Callsites that want to allow that
   need to bypass this higher-level function.
 * Sema: implement coercion of enums and enum literals to unions.
 * Sema: fix comptime mutation of pointers to unions
 * LLVM backend: fully implement proper lowering of union types and
   values according to the union layout, and update the handling of AIR
   instructions that deal with unions to support union layouts.
 * LLVM backend: handle `decl_ref_mut`
   - Maybe this should be unreachable since comptime vars should be
     changed to be non-mutable when they go out of scope, but it's
     harmless for the LLVM backend to support lowering the value.
 * Type: fix `requiresComptime` for optionals, pointers, and some other
   types. This function is still wrong for structs, unions, and enums.
2021-10-14 17:44:46 -07:00
Andrew Kelley
0d4a94f32f stage2: improve handling of 0-bit types and arrays
* Make `alloc` AIR instructions call `resolveTypeLayout`.
 * `Sema.zirResolveInferredAlloc` now calls `requireRuntimeBlock` in the
   case that it operates on a non-comptime instruction.
 * `Type.abiSize` and `Type.abiAlignment` now return 0 for `void`
 * Sema: implement `resolveTypeFields` for unions.
 * LLVM Backend: support `ptr_elem_ptr` when the element type is 0-bit.
 * Type: improve `abiAlignment` implementation for structs to properly
   handle fields with non-default alignment.
 * Value: implement hashing array, vector, and structs.
2021-10-13 21:20:38 -07:00
Andrew Kelley
b0f80ef0d5 stage2: remove use of builtin.stage2_arch workaround
The LLVM backend no longer needs this hack! However, the other backends
still do. So there are still some traces of this workaround in use for now.
2021-10-13 18:43:43 -07:00
Andrew Kelley
df7d6d263e stage2: implement opaque declarations
* Module: implement opaque type namespace lookup
 * Add `Type.type` for convenience
 * Sema: fix `validateVarType` for pointer-to-opaque
 * x86_64 ABI: implement support for pointers
 * LLVM backend: fix lowering of opaque types
 * Type: implement equality checking for opaques
2021-10-13 17:53:28 -07:00
Andrew Kelley
da7fcfd158 stage2: implement Sema for elemVal for comptime slice 2021-10-13 16:31:07 -07:00
Andrew Kelley
e851d89113 Sema: implement comptime coerce_result_ptr and alloc
This is progress towards being able to use `builtin.cpu.arch` instead of
the `stage2_arch` workaround. The next blocker is comptime `elemVal`.
2021-10-13 14:16:01 -07:00
Andrew Kelley
a3104a4a78 stage2: fix comptime stores and sentinel-terminated arrays
* ZIR: the `array_type_sentinel` now has a source node attached to it
   for proper error reporting.
 * Refactor: move `Module.arrayType` to `Type.array`
 * Value: the `bytes` and `array` tags now include the sentinel, if the
   type has one. This simplifies comptime evaluation logic.
 * Sema: fix `zirStructInitEmpty` to properly handle when the type is
   void or a sentinel-terminated array. This handles the syntax `void{}`
   and `[0:X]T{}`.
 * Sema: fix the logic for reporting "cannot store runtime value in
   compile time variable" as well as for emitting a runtime store when a
   pointer value is comptime known but it is a global variable.
 * Sema: implement elemVal for double pointer to array. This can happen
   with this code for example: `var a: *[1]u8 = undefined; _ = a[0];`
 * Sema: Rework the `storePtrVal` function to properly handle nested
   structs and arrays.
   - Also it now handles comptime stores through a bitcasted pointer.
     When the pointer element type and the type according to the Decl
     don't match, the element value is bitcasted before storage.
2021-10-12 21:38:46 -07:00
Andrew Kelley
6d6cf59847 stage2: support nested structs and arrays and sret
* Add AIR instructions: ret_ptr, ret_load
   - This allows Sema to be blissfully unaware of the backend's decision
     to implement by-val/by-ref semantics for struct/union/array types.
     Backends can lower these simply as alloc, load, ret instructions,
     or they can take advantage of them to use a result pointer.
 * Add AIR instruction: array_elem_val
   - Allows for better codegen for `Sema.elemVal`.
 * Implement calculation of ABI alignment and ABI size for unions.
 * Before appending the following AIR instructions to a block,
   resolveTypeLayout is called on the type:
   - call - return type
   - ret - return type
   - store_ptr - elem type
 * Sema: fix memory leak in `zirArrayInit` and other cleanups to this
   function.
 * x86_64: implement the full x86_64 C ABI according to the spec
 * Type: implement `intInfo` for error sets.
 * Type: implement `intTagType` for tagged unions.

The Zig type tag `Fn` is now used exclusively for function bodies.
Function pointers are modeled as `*const T` where `T` is a `Fn` type.
 * The `call` AIR instruction now allows a function pointer operand as
   well as a function operand.
 * Sema now has a coercion from function body to function pointer.
 * Function type syntax, e.g. `fn()void`, now returns zig tag type of
   Pointer with child Fn, rather than Fn directly.
   - I think this should probably be reverted. Will discuss the lang
     specs before doing this. Idea being that function pointers would
     need to be specified as `*const fn()void` rather than `fn() void`.

LLVM backend:
 * Enable calling the panic handler (previously this just
   emitted `@breakpoint()` since the backend could not handle the panic
   function).
 * Implement sret
 * Introduce `isByRef` and implement it for structs and arrays. Types
   that are `isByRef` are now passed as pointers to functions, and e.g.
   `elem_val` will return a pointer instead of doing a load.
 * Move the function type creating code from `resolveLlvmFunction` to
   `llvmType` where it belongs; now there is only 1 instance of this
   logic instead of two.
 * Add the `nonnull` attribute to non-optional pointer parameters.
 * Fix `resolveGlobalDecl` not using fully-qualified names and not using
   the `decl_map`.
 * Implement `genTypedValue` for pointer-like optionals.
 * Fix memory leak when lowering `block` instruction and OOM occurs.
 * Implement volatile checks where relevant.
2021-10-11 11:39:12 -07:00
Matthew Borkowski
784be05a1a stage2: fix astgen for anytype union fields and differentiate anytype vs inferred void in semaUnionFields 2021-10-09 20:39:39 -04:00
Andrew Kelley
73403d897c stage2: add --debug-compile-errors CLI option
This is useful when debugging stage2 and getting an unexpected compile
error, or when rendering a compile error crashes the compiler.
2021-10-07 19:20:15 -07:00
Andrew Kelley
a0c44e806b stage2: fix comptime_float negation 2021-10-07 17:11:27 -07:00
Andrew Kelley
76335bc7ba stage2: implement array literal with explicit type
New ZIR instruction: elem_ptr_imm
This saves some memory for array literals since the element indexes are
communicated as immediate values rather than as references to other ZIR
instructions.
2021-10-07 15:27:05 -07:00
Andrew Kelley
e16ddad49f stage2: enum fixes
* Sema: fix a missing copy on enum tag values
 * LLVM backend: fix lowering of enum constant values for enums with
   specified tag values.
 * Value: fix enumToInt for `enum_numbered` cases.

The float widening behavior tests which rely on compiler-rt symbols are
now passing.
2021-10-05 23:05:14 -07:00
Andrew Kelley
cb616cb797 stage2: implement runtime @intToEnum
* Update AIR instruction `intcast` to allow the dest type to be an
   enum.
 * LLVM backend: update `intcast` to support when the bit counts of
   operand and dest type are the same. This was already a requirement of
   the instruction previously.
 * Type: `intInfo` supports the case when the type is an enum, and
   retrieves the info for the integer tag type. This makes it pretty
   easy for backends to implement `intcast` without having to care
   explicitly that the new type is an enum. As a bonus, simple enums
   never have to go through the type system; their signedness and bit
   count are computed directly.

The "int to enum" behavior test case is now passing for stage2 in the
LLVM backend.
2021-10-05 21:38:47 -07:00
Jacob G-W
5e153b5382 stage2: analyzeSliceLen on comptime slices 2021-10-05 15:46:33 -04:00
Andrew Kelley
78902db68b stage2: fix comptime @bitCast
Before, Sema for comptime `@bitCast` would return the same Value but
change the Type. This gave invalid results because, for example, an
integer Value when the Type is a float would be interpreted numerically,
but `@bitCast` needs it to reinterpret how they would be stored in
memory.

This requires a mechanism to serialize a Value to a byte buffer and
deserialize a Value from a byte buffer.

Not done yet, but needs to happen: comptime dereferencing a pointer
to a Decl needs to perform a comptime bitcast on the loaded value.
Currently the value is silently wrong in the same way that `@bitCast`
was silently wrong before this commit.

The logic in Value for handling readFromMemory for large integers is
only correct for small integers. It needs to be fleshed out for proper
big integers.

As part of this change:
 * std.math.big.Int: initial implementations of readTwosComplement and
   writeTwosComplement. They only support bit_count <= 128 so far and
   panic otherwise.
 * compiler-rt: move the compareXf2 exports over to the stage2 section.
   Even with the improvements in this commit, I'm still seeing test
   failures in the widening behavior tests; more investigation is
   needed.
2021-10-04 23:30:04 -07:00
Robin Voetter
a733692444 Update Value.intTrunc to use new big int truncate 2021-10-04 11:25:29 +02:00
Martin Wickham
1d2c3af906 Remove address of pointer 2021-10-02 15:21:49 -05:00
Martin Wickham
272bad3f12 Delete Module.Scope, move Block into Sema 2021-10-02 15:21:49 -05:00
Martin Wickham
fd60012c21 Change *Scope to *Scope.Block, use Sema when required 2021-10-02 15:21:49 -05:00
Martin Wickham
53a36eacfa Remove my dumb "namespace decl" hack 2021-10-02 15:21:48 -05:00
Martin Wickham
d1a4bdb1f3 Declare generic fn dependency earlier to keep invariant 2021-10-02 15:21:48 -05:00
Martin Wickham
f7c11acb7f Resolve struct fields in a separate sema context 2021-10-02 15:21:48 -05:00
Martin Wickham
993dc2ae77 Fix ownership of array type and elements 2021-10-02 15:21:48 -05:00