257 Commits

Author SHA1 Message Date
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
Matthew Borkowski
ada72c7aa9 astgen.zig: assert that advanceSourceCursor never has to rewind cursor 2021-10-02 08:21:04 -04:00
Matthew Borkowski
c64b885c82 astgen.zig: have defer scopes cache source cursor to reduce redundant scanning during genDefers 2021-10-02 08:20:43 -04:00
Matthew Borkowski
a3842cbafd astgen.zig: make switchExpr generate cases in source order to keep source cursor increasing monotonically 2021-10-02 08:06:26 -04:00
Matthew Borkowski
a1c802cbba astgen.zig: pass lbrace line and column to addFunc to keep source cursor increasing monotonically 2021-10-02 07:56:56 -04:00
Andrew Kelley
99961f22dc stage2: enable building compiler_rt when using LLVM backend
* AstGen: fix emitting `store_to_inferred_ptr` when it should be emitting
   `store` for a variable that has an explicit alignment.
 * Compilation: fix a couple memory leaks
 * Sema: implement support for locals that have specified alignment.
 * Sema: implement `@intCast` when it needs to emit an AIR instruction.
 * Sema: implement `@alignOf`
 * Implement debug printing for extended alloc ZIR instructions.
2021-09-29 00:13:21 -07:00
Andrew Kelley
7efc2a0626 AstGen: improved logic for nodeMayNeedMemoryLocation
* `@as` and `@bitCast` no longer unconditionally return `true` from
   this function; they forward the question to their sub-expression.
 * fix `@splat` incorrectly being marked as needing a memory location
   (this function returns a SIMD vector; it definitely does not want a
   memory location).

Makes AstGen generate slightly nicer ZIR, which in turn generates
slightly nicer AIR, generating slightly nicer machine code in debug
builds.

It also means I can procrastinate implementing the bitcast_result_ptr
ZIR instruction semantic analysis :^)
2021-09-28 20:33:50 -07:00
Andrew Kelley
5467582444 saturating arithmetic modifications
* Remove the builtins `@addWithSaturation`, `@subWithSaturation`,
   `@mulWithSaturation`, and `@shlWithSaturation` now that we have
   first-class syntax for saturating arithmetic.
 * langref: Clarify the behavior of `@shlExact`.
 * Ast: rename `bit_shift_left` to `shl` and `bit_shift_right` to `shr`
   for consistency.
 * Air: rename to include underscore separator with consistency with
   the rest of the ops.
 * Air: add shl_exact instruction
 * Use non-extended tags for saturating arithmetic, to keep it
   simple so that all the arithmetic operations can be done the same
   way.
   - Sema: unify analyzeArithmetic with analyzeSatArithmetic
     - implement comptime `+|`, `-|`, and `*|`
     - allow float operands to saturating arithmetic
 * `<<|` allows any integer type for the RHS.
 * C backend: fix rebase conflicts
 * LLVM backend: reduce the amount of branching for arithmetic ops
 * zig.h: fix magic number not matching actual size of C integer types
2021-09-28 19:19:28 -07:00
Andrew Kelley
71da169c67 AstGen: delete dead code 2021-09-28 17:04:19 -07:00
Travis Staloch
baaec94fe4 sat-arithmetic: create Sema.analyzeSatArithmetic
- similar to Sema.analyzeArithmetic but uses accepts Zir.Inst.Extended.InstData
- missing support for Pointer types and comptime arithmetic
2021-09-28 17:04:18 -07:00
Travis Staloch
bdb90a07bb sat-arithmetic: fixups zig fmt / astcheck 2021-09-28 17:03:43 -07:00
Travis Staloch
b9a95f2dd9 sat-arithmetic: add c backend support
- modify AstGen binOpExt()/assignBinOpExt() to accept generic extended payload T
- rework Sema zirSatArithmetic() to use existing sema.analyzeArithmetic() by adding an `opt_extended` parameter.
- add airSatOp() to codegen/c.zig
- add saturating functions to src/link/C/zig.h
2021-09-28 17:03:41 -07:00
Travis Staloch
29f41896ed sat-arithmetic: add operator support
- adds initial support for the operators +|, -|, *|, <<|, +|=, -|=, *|=, <<|=
- uses operators in addition to builtins in behavior test
- adds binOpExt() and assignBinOpExt() to AstGen.zig. these need to be audited
2021-09-28 17:02:43 -07:00
Martin Wickham
1cc5d4e758
Stage 2: Support inst.func() syntax (#9827)
* Merge call zir instructions to make space for field_call
* Fix bug with comptime known anytype args
* Delete the param_type zir instruction
* Move some passing tests to stage 2
* Implement a.b() function calls
* Add field_call_bind support for call and field builtins
2021-09-28 12:00:35 -05:00
Andrew Kelley
42aa1ea115 stage2: implement @memset and @memcpy builtins 2021-09-24 17:33:06 -07:00
Josh Soref
664941bf14
Spelling corrections (#9833)
Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>
Co-authored-by: Josh Soref <jsoref@users.noreply.github.com>
2021-09-24 13:39:20 -04:00
Martin Wickham
a0a847f2e4
Stage2: Implement comptime closures and the This builtin (#9823) 2021-09-23 13:17:06 -04:00
Andrew Kelley
736d14fd5f stage2: fix AstGen for some struct syntaxes
* AstGen: fix not emitting `struct_init_empty` when an explicit type is
   present in struct initialization syntax.
 * AstGen: these two syntaxes now lower to identical ZIR:
   - `var a = A{ .b = c };`
   - `var a = @as(A, .{ .b = c });`
 * Zir: clarify `auto_enum_tag` in the doc comments.
 * LLVM Backend: fix lowering of function return types when the type has
   0 bits.
2021-09-22 21:06:00 -07:00
Andrew Kelley
aecebf38ac stage2: progress towards ability to compile compiler-rt
* prepare compiler-rt to support being compiled by stage2
   - put in a few minor workarounds that will be removed later, such as
     using `builtin.stage2_arch` rather than `builtin.cpu.arch`.
   - only try to export a few symbols for now - we'll move more symbols
     over to the "working in stage2" section as they become functional
     and gain test coverage.
   - use `inline fn` at function declarations rather than `@call` with an
     always_inline modifier at the callsites, to avoid depending on the
     anonymous array literal syntax language feature (for now).
 * AIR: replace floatcast instruction with fptrunc and fpext for
   shortening and widening floating point values, respectively.
 * Introduce a new ZIR instruction, `export_value`, which implements
   `@export` for the case when the thing to be exported is a local
   comptime value that points to a function.
   - AstGen: fix `@export` not properly reporting ambiguous decl
     references.
 * Sema: handle ExportOptions linkage. The value is now available to all
   backends.
   - Implement setting global linkage as appropriate in the LLVM
     backend. I did not yet inspect the LLVM IR, so this still needs to
     be audited. There is already a pending task to make sure the alias
     stuff is working as intended, and this is related.
   - Sema almost handles section, just a tiny bit more code is needed in
     `resolveExportOptions`.
 * Sema: implement float widening and shortening for both `@floatCast`
   and float coercion.
   - Implement the LLVM backend code for this as well.
2021-09-21 23:21:07 -07:00
Veikka Tuominen
55e7c099ca stage2: various fixes to cImport, sizeOf and types to get tests passing 2021-09-20 20:51:31 -07:00
Veikka Tuominen
9a54ff72df stage2: implement cImport 2021-09-20 20:50:55 -07:00
Robin Voetter
95e83afa98 Address Spaces: Yeet address space on function prototypes
This is a property which solely belongs to pointers to functions,
not to the functions themselves. This cannot be properly represented by
stage 2 at the moment, as type with zigTypeTag() == .Fn is overloaded for
for function pointers and function prototypes.
2021-09-20 02:29:04 +02:00
Robin Voetter
68fcbb5c0d Address Spaces: fmt a bunch of stuff 2021-09-20 02:29:04 +02:00
Robin Voetter
cfbe9a6f61 Address spaces: Forbid addrspace and linksection for local variables 2021-09-20 02:29:03 +02:00
Robin Voetter
805e1bffbd Address Spaces: Sema basics 2021-09-20 02:29:03 +02:00
Robin Voetter
7da9fa6fe2 Address spaces: AstGen
Adds AST generation for address spaces on pointers, function prototypes,
function declarations and variable declarations. In the latter two cases,
declaration properties were already stored more efficiently in a declaration
structure. To accomodate these for address spaces, the bit indicating presence
of a linksection attribute has been extended to include either linksection,
address space, or both.
2021-09-20 02:29:03 +02:00
Andrew Kelley
9fa723ee50 stage2: implement @atomicStore 2021-09-19 15:08:38 -07:00
Ryan Liptak
59f5053bed Update all ensureCapacity calls to the relevant non-deprecated version 2021-09-19 13:52:56 +02:00
Andrew Kelley
b67d1810be stage2: implement @atomicRmw and @atomicLoad
* langref: add some more "see also" links for atomics
 * Add the following AIR instructions
   - atomic_load
   - atomic_store_unordered
   - atomic_store_monotonic
   - atomic_store_release
   - atomic_store_seq_cst
   - atomic_rmw
 * Implement those AIR instructions in LLVM and C backends.
 * AstGen: make the `ty` result locations for `@atomicRmw`, `@atomicLoad`,
   and `@atomicStore` be `coerced_ty` to avoid unnecessary ZIR
   instructions when Sema will be doing the coercions redundantly.
 * Sema for `@atomicLoad` and `@atomicRmw` is done, however Sema for
   `@atomicStore` is not yet implemented.
   - comptime eval for `@atomicRmw` is not yet implemented.
 * Sema: flesh out `coerceInMemoryAllowed` a little bit more. It can now
   handle pointers.
2021-09-15 19:00:35 -07:00
Andrew Kelley
19691c0b17 stage2: implement @fence 2021-09-15 12:37:32 -07:00
Andrew Kelley
0395b35cee stage2: implement cmpxchg and improve comptime eval
* Implement Sema for `@cmpxchgWeak` and `@cmpxchgStrong`. Both runtime
   and comptime codepaths are implement.
 * Implement Codegen for LLVM backend and C backend.
 * Add LazySrcLoc.node_offset_builtin_call_argX 3...5
 * Sema: rework comptime control flow.
   - `error.ComptimeReturn` is used to signal that a comptime function
     call has returned a result (stored in the Inlining struct).
     `analyzeCall` notices this and handles the result.
   - The ZIR instructions `break_inline`, `block_inline`,
     `condbr_inline` are now redundant and can be deleted. `break`,
     `block`, and `condbr` function equivalently inside a comptime scope.
   - The ZIR instructions `loop` and `repeat` also are modified to
     directly perform comptime control flow inside a comptime scope,
     skipping an unnecessary mechanism for analysis of runtime code.
     This makes Zig perform closer to an interpreter when evaluating
     comptime code.
 * Sema: zirRetErrValue looks at Sema.ret_fn_ty rather than sema.func
   for adding to the inferred error set. This fixes a bug for
    inlined/comptime function calls.
 * Implement ZIR printing for cmpxchg.
 * stage1: make cmpxchg respect --single-threaded
   - Our LLVM C++ API wrapper failed to expose this boolean flag before.
 * Fix AIR printing for struct fields showing incorrect liveness data.
2021-09-14 21:58:22 -07:00