287 Commits

Author SHA1 Message Date
Robin Voetter
e18c3f3109 stage2: wrap function prototypes in an inline block.
Previously, function parameter instructions for function prototypes would be
generated in the parent block. This caused issues in blocks where multiple
prototypes would be generated in, such as the block for struct fields for
example. This change introduces an inline block around every prototype such
that all parameters for a prototype are confined to a unique block.
2021-12-21 01:41:50 +01:00
Isaac Freund
9f9f215305
stage1, stage2: rename c_void to anyopaque (#10316)
zig fmt now replaces c_void with anyopaque to make updating
code easy.
2021-12-19 00:24:45 -05:00
Isaac Freund
175463d75d
AstGen: implement @prefetch() builtin 2021-12-10 23:09:02 +01:00
Isaac Freund
47c309c34a
AstGen: increase zig fmt off/on granularity
This enables automatic formatting for a significant amount of code that
currently doesn't deviate from the standard zig fmt enforced style.
2021-12-10 23:09:01 +01:00
Andrew Kelley
cbd653e1d6 AstGen: expr-evaluate asm template expressions
See previous commit 1912ec0323af9a9077a8706157beb8207f6e3eb9 for more
context.

closes #10262
2021-12-02 14:35:35 -07:00
Andrew Kelley
1912ec0323 AstGen: use null string to communicate non-string-literal asm
dd62a6d2e8de522187fd096354e7156cca1821c5 short-circuited the logic of
`asmExpr` by emitting ZIR for `@compileError("...")`. This caused false
positive "unreachable code" errors for stage1 when there was an
expression in the asm template.

This commit makes such cases instead go through logic of `asmExpr` like
normal, however the asm template is set to 0. This is then picked up in
Sema (part of stage2, not stage1) and reported as "assembly code must
use string literal syntax".
2021-12-01 16:24:44 -07:00
Andrew Kelley
7355a20133
Merge pull request #10055 from leecannon/allocator_refactor
Allocgate
2021-11-30 18:48:31 -08:00
Andrew Kelley
dd62a6d2e8 AstGen: allow non-string-literal inline assembly for stage1
The end-game for inline assembly is that the syntax is more integrated
with zig, and it will not allow string concatenation for the assembler
code, for the same reasons that Zig does not have a preprocessor.

However, inline assembly in zig right now is lacking for a variety of
use cases (take a look at the open issues having to do with inline
assembly for example), and being able to use comptime expressions to
concatenate text is a workaround that real-world users are exploiting to
get by in the short term.

This commit keeps "assembly code must use string literal syntax" as a
compile error when using stage2, but allows it through when using
stage1.

I expect to revert this commit after making enough improvements to
inline assembly that our real world users' needs are satisfied.
2021-11-30 19:45:08 -07:00
Lee Cannon
1093b09a98
allocgate: renamed getAllocator function to allocator 2021-11-30 23:32:47 +00:00
Lee Cannon
75548b50ff
allocgate: stage 1 and 2 building 2021-11-30 23:32:47 +00:00
Lee Cannon
85de022c56
allocgate: std Allocator interface refactor 2021-11-30 23:32:47 +00:00
Andrew Kelley
902df103c6 std lib API deprecations for the upcoming 0.9.0 release
See #3811
2021-11-30 00:13:07 -07:00
Andrew Kelley
d3426ce634 AstGen: require binary operations to have reachable operands 2021-11-29 13:21:36 -07:00
Andrew Kelley
c42763f8cc AstGen: use reachableExpr for return operand
Related: #9630
2021-11-24 14:47:33 -07:00
Matthew Borkowski
01842a6ead astgen.zig: avoid temporary allocations by sharing the instructions ArrayList between a GenZir and its sub-blocks wherever their use of it is strictly nested 2021-11-01 05:42:39 -04:00
Matthew Borkowski
65c27e8e66 astgen.zig: delay adding closure_capture instructions to preserve GenZir nesting. Only containers create Namespaces, so the declaring_gz is always the GenZir passed to containerDecl, and containerDecl will always add exactly one instruction (an extended *_decl) to that GenZir. Thus, closure_capture instructions are always lined up immediately after a container decl instruction, so rather than adding them at the point of first mention, where we're nested arbitrarily deep, simply walk through the Namespace captures hash map at the end of each containerDecl branch and add them then. 2021-11-01 05:42:32 -04:00
Matthew Borkowski
92d2aa1b48 astgen.zig: use scratch buffer for temporary allocations in switchExpr and WipMembers 2021-11-01 05:42:25 -04:00
Matthew Borkowski
5760ba949f astgen.zig: simplify container functions by pulling out common processing of members 2021-11-01 05:42:19 -04:00
Matthew Borkowski
e712f87a66 astgen.zig: replace WipDecls with WipMembers, use one allocation to collect container decls, fields, and bits, instead of up to four 2021-11-01 05:41:37 -04:00
Matthew Borkowski
f0260555d6 astgen.zig: simplify switchExpr and collect payload in one ArrayList instead of three 2021-11-01 05:28:03 -04:00
Matthew Borkowski
a0bf620fbf astgen.zig: avoid unnecessary allocation in identifier for @"" syntax 2021-11-01 05:27:52 -04:00
Matthew Borkowski
2561be2e34 astgen.zig: avoid temporary allocations in arrayInit* and structInit*, callExpr, errorSetDecl, typeOf, and builtinCall's compile_log branch 2021-11-01 05:09:19 -04:00
Lee Cannon
83dcfd6205 optimize AstGen.callExpr 2021-10-31 18:11:53 -04:00
Matthew Borkowski
8081e3cbc7 astgen.zig: don't add scopes for extern functions params as they may shadow other names 2021-10-26 18:21:29 -04:00
Robin Voetter
25012ab3d1 astgen: generate correct switch prong indices
Switch prong values are fetched by index in semantic analysis by prong
offset, but these were computed as capture offset. This means that a switch
where the first prong does not capture and the second does, the switch_capture
zir instruction would be assigned switch_prong 0 instead of 1.
2021-10-26 14:51:33 -04:00
Andrew Kelley
8509e7111d stage2: fix switch on tagged union capture-by-pointer
* AstGen: always use `typeof` and never `typeof_elem` on the
   `switch_cond`/`switch_cond_ref` instruction because both variants
   return a value and not a pointer.
   - Delete the `typeof_elem` ZIR instruction since it is no longer
     needed.
 * Sema: validateUnionInit now recognizes a comptime mutable value and
   no longer emits a compile error saying "cannot evaluate constant
   expression"
   - Still to-do is detecting comptime union values in a function that
     is not being executed at compile-time.
     - This is still to-do for structs too.
 * Sema: when emitting a call AIR instruction, call resolveTypeLayout on
   all the parameter types as well as the return type.
 * `Type.structFieldOffset` now works for unions in addition to structs.
2021-10-25 15:11:21 -07:00
Andrew Kelley
8f3e1ea0f0 AstGen: move nodeMayEvalToError logic for builtins
to the declarative BuiltinFn.zig file which lists info about all the
builtin functions.
2021-10-25 10:50:47 -07:00
Matthew Borkowski
9c5b852f9b astgen.zig: emit ZIR for callconv before return type in fnDecl and fnProtoExpr 2021-10-23 22:52:43 -04:00
Matthew Borkowski
8a95bac593 astgen.zig: when ret's operand ResultLoc is .ptr, load from ret_ptr before is_non_err or err_union_code 2021-10-23 20:48:31 -04:00
Matthew Borkowski
096763de98 astgen.zig: fix nodeMayEvalToError 2021-10-23 18:49:23 -04:00
Andrew Kelley
069c83d58c stage2: change @bitCast to always be by-value
After a discussion about language specs, this seems like the best way to
go, because it's simpler to reason about both for humans and compilers.

The `bitcast_result_ptr` ZIR instruction is no longer needed.

This commit also implements writing enums, arrays, and vectors to
virtual memory at compile-time.

This unlocked some more of compiler-rt being able to build, which
in turn unlocks saturating arithmetic behavior tests.

There was also a memory leak in the comptime closure system which is now
fixed.
2021-10-22 15:35:35 -07: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
4cb5fed10b AstGen: make the index variable of inline for a alloc_comptime
Before it was being emitted as an `alloc` which caused inline for loops
to not work correctly.
2021-10-20 15:34:10 -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
Robin Voetter
b65582e834 stage2: remove AstGen none_or_ref
The remaining uses of this result location were causing a bunch of errors
problems where the pointers returned from rvalue and lvalue expressions
would be confused, allowing for extra pointers on rvalue expressions.
For example:
```zig
const X = struct {a: i32};
var x: X = .{.a = 1};
var ptr = &x;
_ = x.a;
```
In the last line, the lookup of x with result location .none_or_ref would
return a double pointer (**X). This would be dereferenced one, after which
a relative pointer to `a` would be fetched and derefenced to get the final
result.

However, this also allows us to manually construct a double pointer, and
fetch the field of the inner type of that:
```zig
_ = &(&(x)).a;
```

This problem also manifests itself with element access. There are two obvious
ways to fix the problem, both of which include replacing the usage of
.none_or_ref for field- and element accesses with something which
deterministically produce either a pointer or value: either result location
.ref or .none. In the former case, this would be paired with .elem_ptr, and
in the latter case with .elem_val.

Note that the stage 1 compiler does not have this problem, because there is
no equivalent of .elem_val and .field_val. In this way it is equivalent to
using the result location .ref for field- and element accesses.

In this case i have used .none, as this matches language behaviour more
closely.
2021-10-20 03:44:02 +02:00
Matthew Borkowski
135cb529de astgen.zig: fix emitting wrong error unwrapping instructions in tryExpr 2021-10-19 13:44:48 -04:00
Matthew Borkowski
79a3dfcfd8 astgen.zig: fix false positive in breakExpr's checking for store_to_block_ptr 2021-10-18 13:18:47 -04: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
f42725c39b
Merge pull request #9925 from mattbork/uniondecl-fixes
stage2: astgen unionDecl fixes
2021-10-10 15:22:17 -04:00
Andrew Kelley
d1fd864da7 translate-c: fix logic for checking primitive names
isZigPrimitiveType had a bug where it checked the integer names (e.g.
u32) before primitives, leading it to incorrectly return `false` for
`undefined` which starts with `u`.

Related: #9928
2021-10-10 11:41:07 -07:00
Matthew Borkowski
ea45062d82 stage2: add astgen errors for untyped union fields and union field values without inferred tag type 2021-10-09 20:39:50 -04: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
75cecef63c stage2: fix returning structs byval from functions 2021-10-07 17:42:17 -07:00
Andrew Kelley
3df19b765d AstGen: make array literals work like struct literals
Now, array literals will emit a coerce_result_ptr ZIR instruction just
like struct literals do. This makes for another passing behavior test case.
2021-10-07 16:01:13 -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
2454459ef5
Merge pull request #9882 from mattbork/astgen-cursor
astgen.zig: keep source cursor increasing monotonically as much as possible
2021-10-04 14:16:33 -04:00
Andrew Kelley
c4df9bf56f AstGen: fix while and for with unreachable bodies
Companion commit to 61a53a587558ff1fe1b0ec98bb424022885edccf.

This commit also moves over a bunch of behavior test cases to the
passing-for-stage2 section.
2021-10-02 20:15:03 -07:00
Andrew Kelley
61a53a5875 AstGen: fix if, orelse, catch, with unreachable bodies
Before, the system to replace a result location pointer with a
traditional break instruction did not notice the case when one of the
bodies was unreachable. Now, the emitted ZIR code is improved and
simplified in this case, resulting in a new passing behavior test.
2021-10-02 19:09:54 -07:00
Matthew Borkowski
bb3ef76434 astgen.zig formatting 2021-10-02 11:44:51 -04:00