@zigc/lib 0.16.0-test.1 → 0.17.0-dev.131
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +19 -0
- package/c/fcntl.zig +6 -1
- package/c/inttypes.zig +0 -10
- package/c/math.zig +138 -114
- package/c/pthread.zig +57 -0
- package/c/search.zig +1 -27
- package/c/stdlib/drand48.zig +0 -57
- package/c/stdlib.zig +0 -100
- package/c/string.zig +20 -7
- package/c/strings.zig +0 -38
- package/c/stropts.zig +17 -0
- package/c/unistd.zig +27 -26
- package/c/wchar.zig +10 -0
- package/c.zig +3 -2
- package/compiler/aro/aro/Attribute/names.zig +604 -589
- package/compiler/aro/aro/Attribute.zig +202 -116
- package/compiler/aro/aro/Builtins/common.zig +874 -863
- package/compiler/aro/aro/Builtins/eval.zig +15 -7
- package/compiler/aro/aro/Builtins.zig +0 -1
- package/compiler/aro/aro/CodeGen.zig +8 -7
- package/compiler/aro/aro/Compilation.zig +137 -111
- package/compiler/aro/aro/Diagnostics.zig +21 -17
- package/compiler/aro/aro/Driver/GCCDetector.zig +635 -0
- package/compiler/aro/aro/Driver.zig +138 -63
- package/compiler/aro/aro/LangOpts.zig +12 -2
- package/compiler/aro/aro/Parser/Diagnostic.zig +79 -19
- package/compiler/aro/aro/Parser.zig +352 -153
- package/compiler/aro/aro/Pragma.zig +3 -2
- package/compiler/aro/aro/Preprocessor/Diagnostic.zig +21 -0
- package/compiler/aro/aro/Preprocessor.zig +136 -62
- package/compiler/aro/aro/Target.zig +17 -12
- package/compiler/aro/aro/Tokenizer.zig +31 -14
- package/compiler/aro/aro/Toolchain.zig +4 -7
- package/compiler/aro/aro/Tree.zig +178 -148
- package/compiler/aro/aro/TypeStore.zig +82 -24
- package/compiler/aro/aro/Value.zig +13 -17
- package/compiler/aro/aro/features.zig +1 -0
- package/compiler/aro/aro/pragmas/message.zig +3 -2
- package/compiler/aro/aro/pragmas/once.zig +0 -1
- package/compiler/aro/aro/record_layout.zig +3 -3
- package/compiler/aro/aro/text_literal.zig +3 -2
- package/compiler/aro/assembly_backend/x86_64.zig +7 -8
- package/compiler/aro/backend/Assembly.zig +1 -2
- package/compiler/aro/backend/Interner.zig +2 -2
- package/compiler/aro/backend/Ir.zig +100 -92
- package/compiler/aro/include/ptrcheck.h +49 -0
- package/compiler/aro/main.zig +26 -10
- package/compiler/build_runner.zig +1 -2
- package/compiler/objdump.zig +93 -0
- package/compiler/reduce/Walk.zig +7 -7
- package/compiler/reduce.zig +5 -1
- package/compiler/resinator/compile.zig +2 -2
- package/compiler/resinator/main.zig +7 -1
- package/compiler/resinator/preprocess.zig +1 -3
- package/compiler/std-docs.zig +8 -1
- package/compiler/test_runner.zig +194 -62
- package/compiler/translate-c/MacroTranslator.zig +80 -11
- package/compiler/translate-c/PatternList.zig +1 -9
- package/compiler/translate-c/Scope.zig +43 -6
- package/compiler/translate-c/Translator.zig +369 -127
- package/compiler/translate-c/ast.zig +19 -11
- package/compiler/translate-c/main.zig +76 -17
- package/compiler_rt/cos.zig +140 -53
- package/compiler_rt/divmodei4.zig +40 -17
- package/compiler_rt/exp.zig +1 -6
- package/compiler_rt/exp2.zig +1 -6
- package/compiler_rt/exp_f128.zig +377 -0
- package/compiler_rt/fabs.zig +0 -2
- package/compiler_rt/fma.zig +0 -2
- package/compiler_rt/fmax.zig +0 -2
- package/compiler_rt/fmin.zig +0 -2
- package/compiler_rt/fmod.zig +0 -2
- package/compiler_rt/limb64.zig +1127 -0
- package/compiler_rt/log.zig +0 -2
- package/compiler_rt/log10.zig +0 -2
- package/compiler_rt/log2.zig +0 -2
- package/compiler_rt/long_double.zig +37 -0
- package/compiler_rt/mulXi3.zig +1 -1
- package/compiler_rt/mulo.zig +6 -1
- package/compiler_rt/rem_pio2l.zig +173 -0
- package/compiler_rt/round.zig +0 -2
- package/compiler_rt/sin.zig +139 -56
- package/compiler_rt/sincos.zig +277 -72
- package/compiler_rt/sqrt.zig +0 -2
- package/compiler_rt/ssp.zig +1 -1
- package/compiler_rt/tan.zig +117 -48
- package/compiler_rt/trig.zig +256 -6
- package/compiler_rt/trunc.zig +0 -2
- package/compiler_rt/udivmodei4.zig +28 -0
- package/compiler_rt.zig +2 -0
- package/fuzzer.zig +857 -307
- package/libc/musl/arch/mipsn32/syscall_arch.h +35 -32
- package/libc/musl/src/math/pow.c +343 -0
- package/package.json +1 -1
- package/std/Build/Cache.zig +6 -6
- package/std/Build/Fuzz.zig +6 -19
- package/std/Build/Module.zig +1 -1
- package/std/Build/Step/CheckObject.zig +3 -3
- package/std/Build/Step/Compile.zig +18 -1
- package/std/Build/Step/ConfigHeader.zig +49 -33
- package/std/Build/Step/InstallArtifact.zig +18 -0
- package/std/Build/Step/Run.zig +538 -89
- package/std/Build/Step/TranslateC.zig +0 -6
- package/std/Build/Step.zig +10 -19
- package/std/Build/WebServer.zig +31 -19
- package/std/Build/abi.zig +47 -11
- package/std/Build.zig +17 -17
- package/std/Io/Dir.zig +7 -2
- package/std/Io/Dispatch.zig +5 -13
- package/std/Io/File/Reader.zig +3 -1
- package/std/Io/File/Writer.zig +8 -6
- package/std/Io/File.zig +1 -0
- package/std/Io/Kqueue.zig +2 -2
- package/std/Io/Reader.zig +8 -9
- package/std/Io/Semaphore.zig +112 -17
- package/std/Io/Terminal.zig +1 -1
- package/std/Io/Threaded.zig +352 -180
- package/std/Io/Uring.zig +15 -16
- package/std/Io/Writer.zig +46 -42
- package/std/Io/net.zig +11 -11
- package/std/Io.zig +1052 -20
- package/std/SemanticVersion.zig +1 -1
- package/std/Target/Query.zig +2 -2
- package/std/Target.zig +53 -7
- package/std/Thread.zig +8 -3
- package/std/array_hash_map.zig +105 -573
- package/std/array_list.zig +22 -31
- package/std/bit_set.zig +22 -6
- package/std/builtin/assembly.zig +68 -0
- package/std/builtin.zig +4 -0
- package/std/c/haiku.zig +3 -0
- package/std/c/serenity.zig +1 -6
- package/std/c.zig +106 -24
- package/std/compress/flate/Compress.zig +3 -3
- package/std/compress/flate/Decompress.zig +2 -3
- package/std/compress/zstd/Decompress.zig +2 -4
- package/std/crypto/Certificate/Bundle.zig +15 -1
- package/std/crypto/Certificate.zig +13 -1
- package/std/crypto/ascon.zig +75 -33
- package/std/crypto/codecs/asn1/Oid.zig +12 -1
- package/std/crypto/codecs/asn1.zig +33 -18
- package/std/crypto/codecs/base64_hex_ct.zig +16 -8
- package/std/crypto/ml_kem.zig +2 -9
- package/std/crypto/tls/Client.zig +79 -4
- package/std/crypto/tls.zig +1 -1
- package/std/crypto.zig +1 -0
- package/std/debug/Dwarf.zig +29 -9
- package/std/debug/Info.zig +4 -0
- package/std/debug/MachOFile.zig +46 -8
- package/std/debug/Pdb.zig +540 -37
- package/std/debug/SelfInfo/Elf.zig +19 -18
- package/std/debug/SelfInfo/MachO.zig +18 -7
- package/std/debug/SelfInfo/Windows.zig +138 -36
- package/std/debug.zig +181 -66
- package/std/enums.zig +25 -19
- package/std/fmt.zig +8 -3
- package/std/fs/path.zig +6 -4
- package/std/heap/ArenaAllocator.zig +145 -154
- package/std/heap/BufferFirstAllocator.zig +165 -0
- package/std/heap/debug_allocator.zig +7 -7
- package/std/heap.zig +2 -126
- package/std/http/Client.zig +31 -30
- package/std/http.zig +14 -13
- package/std/json/Scanner.zig +2 -2
- package/std/json/Stringify.zig +3 -3
- package/std/json/dynamic.zig +4 -4
- package/std/math/big/int.zig +16 -17
- package/std/mem/Allocator.zig +4 -5
- package/std/mem.zig +48 -0
- package/std/os/emscripten.zig +2 -18
- package/std/os/linux/IoUring.zig +2 -0
- package/std/os/linux/aarch64.zig +41 -12
- package/std/os/linux/arc.zig +173 -0
- package/std/os/linux/arm.zig +41 -12
- package/std/os/linux/hexagon.zig +33 -11
- package/std/os/linux/loongarch32.zig +41 -13
- package/std/os/linux/loongarch64.zig +41 -12
- package/std/os/linux/m68k.zig +41 -13
- package/std/os/linux/mips.zig +67 -36
- package/std/os/linux/mips64.zig +60 -29
- package/std/os/linux/mipsn32.zig +60 -29
- package/std/os/linux/or1k.zig +41 -12
- package/std/os/linux/powerpc.zig +41 -12
- package/std/os/linux/powerpc64.zig +41 -12
- package/std/os/linux/riscv32.zig +41 -12
- package/std/os/linux/riscv64.zig +41 -12
- package/std/os/linux/s390x.zig +44 -7
- package/std/os/linux/sparc64.zig +83 -52
- package/std/os/linux/thumb.zig +52 -36
- package/std/os/linux/x32.zig +41 -12
- package/std/os/linux/x86.zig +42 -13
- package/std/os/linux/x86_64.zig +41 -12
- package/std/os/linux.zig +419 -438
- package/std/os/uefi/tables/boot_services.zig +9 -8
- package/std/os/windows.zig +2 -2
- package/std/os.zig +41 -0
- package/std/pdb.zig +143 -4
- package/std/posix.zig +6 -12
- package/std/priority_dequeue.zig +13 -12
- package/std/priority_queue.zig +5 -4
- package/std/process/Child.zig +1 -1
- package/std/process/Environ.zig +1 -1
- package/std/process.zig +1 -1
- package/std/sort.zig +3 -3
- package/std/start.zig +17 -4
- package/std/std.zig +19 -6
- package/std/testing/FailingAllocator.zig +4 -4
- package/std/testing/Smith.zig +37 -2
- package/std/zig/Ast/Render.zig +187 -459
- package/std/zig/Ast.zig +0 -4
- package/std/zig/AstGen.zig +86 -103
- package/std/zig/AstRlAnnotate.zig +0 -11
- package/std/zig/AstSmith.zig +2602 -0
- package/std/zig/BuiltinFn.zig +0 -32
- package/std/zig/Client.zig +8 -3
- package/std/zig/LibCInstallation.zig +4 -3
- package/std/zig/Parse.zig +90 -81
- package/std/zig/Server.zig +26 -0
- package/std/zig/WindowsSdk.zig +13 -13
- package/std/zig/Zir.zig +66 -62
- package/std/zig/ZonGen.zig +6 -5
- package/std/zig/c_translation/helpers.zig +14 -9
- package/std/zig/llvm/Builder.zig +119 -60
- package/std/zig/system.zig +20 -4
- package/std/zig/tokenizer.zig +2 -1
- package/std/zig.zig +7 -10
- package/std/zip.zig +5 -5
- package/zig.h +340 -1
- package/compiler/aro/aro/Driver/Filesystem.zig +0 -241
- package/libc/mingw/complex/cabs.c +0 -48
- package/libc/mingw/complex/cabsf.c +0 -48
- package/libc/mingw/complex/cacos.c +0 -50
- package/libc/mingw/complex/cacosf.c +0 -50
- package/libc/mingw/complex/carg.c +0 -48
- package/libc/mingw/complex/cargf.c +0 -48
- package/libc/mingw/complex/casin.c +0 -50
- package/libc/mingw/complex/casinf.c +0 -50
- package/libc/mingw/complex/catan.c +0 -50
- package/libc/mingw/complex/catanf.c +0 -50
- package/libc/mingw/complex/ccos.c +0 -50
- package/libc/mingw/complex/ccosf.c +0 -50
- package/libc/mingw/complex/cexp.c +0 -48
- package/libc/mingw/complex/cexpf.c +0 -48
- package/libc/mingw/complex/cimag.c +0 -48
- package/libc/mingw/complex/cimagf.c +0 -48
- package/libc/mingw/complex/clog.c +0 -48
- package/libc/mingw/complex/clog10.c +0 -49
- package/libc/mingw/complex/clog10f.c +0 -49
- package/libc/mingw/complex/clogf.c +0 -48
- package/libc/mingw/complex/conj.c +0 -48
- package/libc/mingw/complex/conjf.c +0 -48
- package/libc/mingw/complex/cpow.c +0 -48
- package/libc/mingw/complex/cpowf.c +0 -48
- package/libc/mingw/complex/cproj.c +0 -48
- package/libc/mingw/complex/cprojf.c +0 -48
- package/libc/mingw/complex/creal.c +0 -48
- package/libc/mingw/complex/crealf.c +0 -48
- package/libc/mingw/complex/csin.c +0 -50
- package/libc/mingw/complex/csinf.c +0 -50
- package/libc/mingw/complex/csqrt.c +0 -48
- package/libc/mingw/complex/csqrtf.c +0 -48
- package/libc/mingw/complex/ctan.c +0 -50
- package/libc/mingw/complex/ctanf.c +0 -50
- package/libc/mingw/math/arm/s_rint.c +0 -86
- package/libc/mingw/math/arm/s_rintf.c +0 -51
- package/libc/mingw/math/arm/sincos.S +0 -30
- package/libc/mingw/math/arm-common/sincosl.c +0 -13
- package/libc/mingw/math/arm64/rint.c +0 -12
- package/libc/mingw/math/arm64/rintf.c +0 -12
- package/libc/mingw/math/arm64/sincos.S +0 -32
- package/libc/mingw/math/bsd_private_base.h +0 -148
- package/libc/mingw/math/fdiml.c +0 -24
- package/libc/mingw/math/frexpf.c +0 -13
- package/libc/mingw/math/frexpl.c +0 -71
- package/libc/mingw/math/x86/acosf.c +0 -29
- package/libc/mingw/math/x86/atanf.c +0 -23
- package/libc/mingw/math/x86/atanl.c +0 -18
- package/libc/mingw/math/x86/cos.def.h +0 -65
- package/libc/mingw/math/x86/cosl.c +0 -46
- package/libc/mingw/math/x86/cosl_internal.S +0 -55
- package/libc/mingw/math/x86/ldexp.c +0 -23
- package/libc/mingw/math/x86/scalbn.S +0 -41
- package/libc/mingw/math/x86/scalbnf.S +0 -40
- package/libc/mingw/math/x86/sin.def.h +0 -65
- package/libc/mingw/math/x86/sinl.c +0 -46
- package/libc/mingw/math/x86/sinl_internal.S +0 -58
- package/libc/mingw/math/x86/tanl.S +0 -62
- package/libc/mingw/misc/btowc.c +0 -28
- package/libc/mingw/misc/wcstof.c +0 -66
- package/libc/mingw/misc/wcstoimax.c +0 -132
- package/libc/mingw/misc/wcstoumax.c +0 -126
- package/libc/mingw/misc/wctob.c +0 -29
- package/libc/mingw/misc/winbs_uint64.c +0 -6
- package/libc/mingw/misc/winbs_ulong.c +0 -6
- package/libc/mingw/misc/winbs_ushort.c +0 -6
- package/libc/mingw/stdio/_Exit.c +0 -10
- package/libc/mingw/stdio/_findfirst64i32.c +0 -21
- package/libc/mingw/stdio/_findnext64i32.c +0 -21
- package/libc/mingw/stdio/_fstat64i32.c +0 -37
- package/libc/mingw/stdio/_stat64i32.c +0 -37
- package/libc/mingw/stdio/_wfindfirst64i32.c +0 -21
- package/libc/mingw/stdio/_wfindnext64i32.c +0 -21
- package/libc/mingw/stdio/_wstat64i32.c +0 -37
- package/libc/mingw/winpthreads/spinlock.c +0 -82
- package/libc/musl/src/legacy/isastream.c +0 -7
- package/libc/musl/src/legacy/valloc.c +0 -8
- package/libc/musl/src/linux/tee.c +0 -8
- package/libc/musl/src/math/__cosl.c +0 -96
- package/libc/musl/src/math/__sinl.c +0 -78
- package/libc/musl/src/math/__tanl.c +0 -143
- package/libc/musl/src/math/aarch64/lrint.c +0 -10
- package/libc/musl/src/math/aarch64/lrintf.c +0 -10
- package/libc/musl/src/math/aarch64/rintf.c +0 -7
- package/libc/musl/src/math/cosl.c +0 -39
- package/libc/musl/src/math/fdim.c +0 -10
- package/libc/musl/src/math/fdimf.c +0 -10
- package/libc/musl/src/math/fdiml.c +0 -18
- package/libc/musl/src/math/finite.c +0 -7
- package/libc/musl/src/math/finitef.c +0 -7
- package/libc/musl/src/math/frexp.c +0 -23
- package/libc/musl/src/math/frexpf.c +0 -23
- package/libc/musl/src/math/frexpl.c +0 -29
- package/libc/musl/src/math/i386/lrint.c +0 -8
- package/libc/musl/src/math/i386/lrintf.c +0 -8
- package/libc/musl/src/math/i386/rintf.c +0 -7
- package/libc/musl/src/math/lrint.c +0 -72
- package/libc/musl/src/math/lrintf.c +0 -8
- package/libc/musl/src/math/powerpc64/lrint.c +0 -16
- package/libc/musl/src/math/powerpc64/lrintf.c +0 -16
- package/libc/musl/src/math/rintf.c +0 -30
- package/libc/musl/src/math/s390x/rintf.c +0 -15
- package/libc/musl/src/math/sincosl.c +0 -60
- package/libc/musl/src/math/sinl.c +0 -41
- package/libc/musl/src/math/tanl.c +0 -29
- package/libc/musl/src/math/x32/lrint.s +0 -5
- package/libc/musl/src/math/x32/lrintf.s +0 -5
- package/libc/musl/src/math/x86_64/lrint.c +0 -8
- package/libc/musl/src/math/x86_64/lrintf.c +0 -8
- package/libc/musl/src/string/strdup.c +0 -10
- package/libc/musl/src/string/strndup.c +0 -12
- package/libc/musl/src/string/wcsdup.c +0 -10
- package/libc/musl/src/thread/pthread_spin_destroy.c +0 -6
- package/libc/musl/src/thread/pthread_spin_init.c +0 -6
- package/libc/musl/src/thread/pthread_spin_lock.c +0 -8
- package/libc/musl/src/thread/pthread_spin_trylock.c +0 -7
- package/libc/musl/src/thread/pthread_spin_unlock.c +0 -7
- package/libc/musl/src/unistd/dup2.c +0 -20
- package/libc/musl/src/unistd/dup3.c +0 -26
- package/libc/wasi/libc-bottom-half/sources/reallocarray.c +0 -14
- package/libc/wasi/thread-stub/pthread_spin_lock.c +0 -8
- package/libc/wasi/thread-stub/pthread_spin_trylock.c +0 -8
- package/libc/wasi/thread-stub/pthread_spin_unlock.c +0 -7
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
const std = @import("std");
|
|
2
|
-
const Io = std.Io;
|
|
3
2
|
const mem = std.mem;
|
|
4
3
|
const Allocator = mem.Allocator;
|
|
5
4
|
const assert = std.debug.assert;
|
|
@@ -204,6 +203,11 @@ string_ids: struct {
|
|
|
204
203
|
sigjmp_buf: StringId,
|
|
205
204
|
ucontext_t: StringId,
|
|
206
205
|
},
|
|
206
|
+
va_arg_pack_ctx: packed struct {
|
|
207
|
+
valid: bool = false,
|
|
208
|
+
variadic: bool = false,
|
|
209
|
+
typed: bool = false,
|
|
210
|
+
} = .{},
|
|
207
211
|
|
|
208
212
|
/// Checks codepoint for various pedantic warnings
|
|
209
213
|
/// Returns true if diagnostic issued
|
|
@@ -211,8 +215,9 @@ fn checkIdentifierCodepointWarnings(p: *Parser, codepoint: u21, loc: Source.Loca
|
|
|
211
215
|
assert(codepoint >= 0x80);
|
|
212
216
|
|
|
213
217
|
const prev_total = p.diagnostics.total;
|
|
214
|
-
var
|
|
215
|
-
var
|
|
218
|
+
var bfa_buf: [1024]u8 = undefined;
|
|
219
|
+
var bfa: std.heap.BufferFirstAllocator = .init(&bfa_buf, p.comp.gpa);
|
|
220
|
+
var allocating: std.Io.Writer.Allocating = .init(bfa.allocator());
|
|
216
221
|
defer allocating.deinit();
|
|
217
222
|
|
|
218
223
|
if (!char_info.isC99IdChar(codepoint)) {
|
|
@@ -425,8 +430,9 @@ pub fn err(p: *Parser, tok_i: TokenIndex, diagnostic: Diagnostic, args: anytype)
|
|
|
425
430
|
if (diagnostic.suppress_unless_version) |some| if (!p.comp.langopts.standard.atLeast(some)) return;
|
|
426
431
|
if (p.diagnostics.effectiveKind(diagnostic) == .off) return;
|
|
427
432
|
|
|
428
|
-
var
|
|
429
|
-
var
|
|
433
|
+
var bfa_buf: [1024]u8 = undefined;
|
|
434
|
+
var bfa: std.heap.BufferFirstAllocator = .init(&bfa_buf, p.comp.gpa);
|
|
435
|
+
var allocating: std.Io.Writer.Allocating = .init(bfa.allocator());
|
|
430
436
|
defer allocating.deinit();
|
|
431
437
|
|
|
432
438
|
p.formatArgs(&allocating.writer, diagnostic.fmt, args) catch return error.OutOfMemory;
|
|
@@ -448,7 +454,7 @@ pub fn err(p: *Parser, tok_i: TokenIndex, diagnostic: Diagnostic, args: anytype)
|
|
|
448
454
|
}, p.pp.expansionSlice(tok_i), true);
|
|
449
455
|
}
|
|
450
456
|
|
|
451
|
-
fn formatArgs(p: *Parser, w: *Io.Writer, fmt: []const u8, args: anytype) !void {
|
|
457
|
+
fn formatArgs(p: *Parser, w: *std.Io.Writer, fmt: []const u8, args: anytype) !void {
|
|
452
458
|
var i: usize = 0;
|
|
453
459
|
inline for (std.meta.fields(@TypeOf(args))) |arg_info| {
|
|
454
460
|
const arg = @field(args, arg_info.name);
|
|
@@ -477,13 +483,13 @@ fn formatArgs(p: *Parser, w: *Io.Writer, fmt: []const u8, args: anytype) !void {
|
|
|
477
483
|
try w.writeAll(fmt[i..]);
|
|
478
484
|
}
|
|
479
485
|
|
|
480
|
-
fn formatTokenId(w: *Io.Writer, fmt: []const u8, tok_id: Tree.Token.Id) !usize {
|
|
486
|
+
fn formatTokenId(w: *std.Io.Writer, fmt: []const u8, tok_id: Tree.Token.Id) !usize {
|
|
481
487
|
const i = Diagnostics.templateIndex(w, fmt, "{tok_id}");
|
|
482
488
|
try w.writeAll(tok_id.symbol());
|
|
483
489
|
return i;
|
|
484
490
|
}
|
|
485
491
|
|
|
486
|
-
fn formatQualType(p: *Parser, w: *Io.Writer, fmt: []const u8, qt: QualType) !usize {
|
|
492
|
+
fn formatQualType(p: *Parser, w: *std.Io.Writer, fmt: []const u8, qt: QualType) !usize {
|
|
487
493
|
const i = Diagnostics.templateIndex(w, fmt, "{qt}");
|
|
488
494
|
try w.writeByte('\'');
|
|
489
495
|
try qt.print(p.comp, w);
|
|
@@ -502,7 +508,7 @@ fn formatQualType(p: *Parser, w: *Io.Writer, fmt: []const u8, qt: QualType) !usi
|
|
|
502
508
|
return i;
|
|
503
509
|
}
|
|
504
510
|
|
|
505
|
-
fn formatResult(p: *Parser, w: *Io.Writer, fmt: []const u8, res: Result) !usize {
|
|
511
|
+
fn formatResult(p: *Parser, w: *std.Io.Writer, fmt: []const u8, res: Result) !usize {
|
|
506
512
|
const i = Diagnostics.templateIndex(w, fmt, "{value}");
|
|
507
513
|
switch (res.val.opt_ref) {
|
|
508
514
|
.none => try w.writeAll("(none)"),
|
|
@@ -525,7 +531,7 @@ const Normalized = struct {
|
|
|
525
531
|
return .{ .str = str };
|
|
526
532
|
}
|
|
527
533
|
|
|
528
|
-
pub fn format(ctx: Normalized, w: *Io.Writer, fmt: []const u8) !usize {
|
|
534
|
+
pub fn format(ctx: Normalized, w: *std.Io.Writer, fmt: []const u8) !usize {
|
|
529
535
|
const i = Diagnostics.templateIndex(w, fmt, "{normalized}");
|
|
530
536
|
var it: std.unicode.Utf8Iterator = .{
|
|
531
537
|
.bytes = ctx.str,
|
|
@@ -559,7 +565,7 @@ const Codepoint = struct {
|
|
|
559
565
|
return .{ .codepoint = codepoint };
|
|
560
566
|
}
|
|
561
567
|
|
|
562
|
-
pub fn format(ctx: Codepoint, w: *Io.Writer, fmt: []const u8) !usize {
|
|
568
|
+
pub fn format(ctx: Codepoint, w: *std.Io.Writer, fmt: []const u8) !usize {
|
|
563
569
|
const i = Diagnostics.templateIndex(w, fmt, "{codepoint}");
|
|
564
570
|
try w.print("{X:0>4}", .{ctx.codepoint});
|
|
565
571
|
return i;
|
|
@@ -573,7 +579,7 @@ const Escaped = struct {
|
|
|
573
579
|
return .{ .str = str };
|
|
574
580
|
}
|
|
575
581
|
|
|
576
|
-
pub fn format(ctx: Escaped, w: *Io.Writer, fmt: []const u8) !usize {
|
|
582
|
+
pub fn format(ctx: Escaped, w: *std.Io.Writer, fmt: []const u8) !usize {
|
|
577
583
|
const i = Diagnostics.templateIndex(w, fmt, "{s}");
|
|
578
584
|
try std.zig.stringEscape(ctx.str, w);
|
|
579
585
|
return i;
|
|
@@ -740,6 +746,11 @@ fn getNode(p: *Parser, node: Node.Index, comptime tag: std.meta.Tag(Tree.Node))
|
|
|
740
746
|
}
|
|
741
747
|
}
|
|
742
748
|
|
|
749
|
+
pub fn isAddressOfStringLiteral(p: *Parser, node: Node.Index) bool {
|
|
750
|
+
const addr_of = p.getNode(node, .addr_of_expr) orelse return false;
|
|
751
|
+
return p.nodeIs(addr_of.operand, .string_literal_expr);
|
|
752
|
+
}
|
|
753
|
+
|
|
743
754
|
fn pragma(p: *Parser) Compilation.Error!bool {
|
|
744
755
|
var found_pragma = false;
|
|
745
756
|
while (p.eatToken(.keyword_pragma)) |_| {
|
|
@@ -1070,14 +1081,15 @@ fn decl(p: *Parser) Error!bool {
|
|
|
1070
1081
|
|
|
1071
1082
|
try p.attributeSpecifier();
|
|
1072
1083
|
|
|
1084
|
+
const decl_spec_start = p.tok_i;
|
|
1073
1085
|
var decl_spec = (try p.declSpec()) orelse blk: {
|
|
1074
1086
|
if (p.func.qt != null) {
|
|
1075
1087
|
p.tok_i = first_tok;
|
|
1076
1088
|
return false;
|
|
1077
1089
|
}
|
|
1078
|
-
switch (p.tok_ids[
|
|
1090
|
+
switch (p.tok_ids[decl_spec_start]) {
|
|
1079
1091
|
.asterisk, .l_paren => {},
|
|
1080
|
-
.identifier, .extended_identifier => switch (p.tok_ids[
|
|
1092
|
+
.identifier, .extended_identifier => switch (p.tok_ids[decl_spec_start + 1]) {
|
|
1081
1093
|
.identifier, .extended_identifier => {
|
|
1082
1094
|
// The most likely reason for `identifier identifier` is
|
|
1083
1095
|
// an unknown type name.
|
|
@@ -1087,7 +1099,7 @@ fn decl(p: *Parser) Error!bool {
|
|
|
1087
1099
|
},
|
|
1088
1100
|
else => {},
|
|
1089
1101
|
},
|
|
1090
|
-
else => if (p.tok_i !=
|
|
1102
|
+
else => if (p.tok_i != decl_spec_start) {
|
|
1091
1103
|
try p.err(p.tok_i, .expected_ident_or_l_paren, .{});
|
|
1092
1104
|
return error.ParsingFailed;
|
|
1093
1105
|
} else return false,
|
|
@@ -1167,6 +1179,7 @@ fn decl(p: *Parser) Error!bool {
|
|
|
1167
1179
|
|
|
1168
1180
|
// Collect old style parameter declarations.
|
|
1169
1181
|
if (init_d.d.old_style_func != null) {
|
|
1182
|
+
try p.err(init_d.d.name, .def_no_proto_deprecated, .{});
|
|
1170
1183
|
const param_buf_top = p.param_buf.items.len;
|
|
1171
1184
|
defer p.param_buf.items.len = param_buf_top;
|
|
1172
1185
|
|
|
@@ -1340,7 +1353,7 @@ fn decl(p: *Parser) Error!bool {
|
|
|
1340
1353
|
if (init_d.d.old_style_func) |tok_i| try p.err(tok_i, .invalid_old_style_params, .{});
|
|
1341
1354
|
|
|
1342
1355
|
if (decl_spec.storage_class == .typedef) {
|
|
1343
|
-
try decl_spec.validateDecl(p);
|
|
1356
|
+
try decl_spec.validateDecl(p, init_d.asm_label);
|
|
1344
1357
|
try p.tree.setNode(.{ .typedef = .{
|
|
1345
1358
|
.name_tok = init_d.d.name,
|
|
1346
1359
|
.qt = init_d.d.qt,
|
|
@@ -1357,7 +1370,7 @@ fn decl(p: *Parser) Error!bool {
|
|
|
1357
1370
|
.definition = null,
|
|
1358
1371
|
} }, @intFromEnum(decl_node));
|
|
1359
1372
|
} else {
|
|
1360
|
-
try decl_spec.validateDecl(p);
|
|
1373
|
+
try decl_spec.validateDecl(p, init_d.asm_label);
|
|
1361
1374
|
var node_qt = init_d.d.qt;
|
|
1362
1375
|
if (p.func.qt == null and decl_spec.storage_class != .@"extern") {
|
|
1363
1376
|
if (node_qt.get(p.comp, .array)) |array_ty| {
|
|
@@ -1454,7 +1467,7 @@ fn decl(p: *Parser) Error!bool {
|
|
|
1454
1467
|
return true;
|
|
1455
1468
|
}
|
|
1456
1469
|
|
|
1457
|
-
fn staticAssertMessage(p: *Parser, cond_node: Node.Index, maybe_message: ?Result, allocating: *Io.Writer.Allocating) !?[]const u8 {
|
|
1470
|
+
fn staticAssertMessage(p: *Parser, cond_node: Node.Index, maybe_message: ?Result, allocating: *std.Io.Writer.Allocating) !?[]const u8 {
|
|
1458
1471
|
const w = &allocating.writer;
|
|
1459
1472
|
|
|
1460
1473
|
const cond = cond_node.get(&p.tree);
|
|
@@ -1526,8 +1539,9 @@ fn staticAssert(p: *Parser) Error!bool {
|
|
|
1526
1539
|
}
|
|
1527
1540
|
} else {
|
|
1528
1541
|
if (!res.val.toBool(p.comp)) {
|
|
1529
|
-
var
|
|
1530
|
-
var
|
|
1542
|
+
var bfa_buf: [1024]u8 = undefined;
|
|
1543
|
+
var bfa: std.heap.BufferFirstAllocator = .init(&bfa_buf, gpa);
|
|
1544
|
+
var allocating: std.Io.Writer.Allocating = .init(bfa.allocator());
|
|
1531
1545
|
defer allocating.deinit();
|
|
1532
1546
|
|
|
1533
1547
|
if (p.staticAssertMessage(res_node, str, &allocating) catch return error.OutOfMemory) |message| {
|
|
@@ -1597,13 +1611,16 @@ pub const DeclSpec = struct {
|
|
|
1597
1611
|
if (d.constexpr) |tok_i| try p.err(tok_i, .illegal_storage_on_func, .{});
|
|
1598
1612
|
}
|
|
1599
1613
|
|
|
1600
|
-
fn validateDecl(d: DeclSpec, p: *Parser) Error!void {
|
|
1614
|
+
fn validateDecl(d: DeclSpec, p: *Parser, asm_label: ?Node.Index) Error!void {
|
|
1601
1615
|
if (d.@"inline") |tok_i| try p.err(tok_i, .func_spec_non_func, .{"inline"});
|
|
1602
1616
|
// TODO move to attribute validation
|
|
1603
1617
|
if (d.noreturn) |tok_i| try p.err(tok_i, .func_spec_non_func, .{"_Noreturn"});
|
|
1604
1618
|
switch (d.storage_class) {
|
|
1605
|
-
.auto =>
|
|
1606
|
-
|
|
1619
|
+
.auto => {
|
|
1620
|
+
std.debug.assert(!p.comp.langopts.standard.atLeast(.c23));
|
|
1621
|
+
try p.err(p.tok_i, .auto_on_global, .{});
|
|
1622
|
+
},
|
|
1623
|
+
.register => if (p.func.qt == null and asm_label == null) try p.err(p.tok_i, .register_on_global, .{}),
|
|
1607
1624
|
else => {},
|
|
1608
1625
|
}
|
|
1609
1626
|
}
|
|
@@ -1787,7 +1804,11 @@ fn storageClassSpec(p: *Parser, d: *DeclSpec) Error!bool {
|
|
|
1787
1804
|
return p.tok_i != start;
|
|
1788
1805
|
}
|
|
1789
1806
|
|
|
1790
|
-
const InitDeclarator = struct {
|
|
1807
|
+
const InitDeclarator = struct {
|
|
1808
|
+
d: Declarator,
|
|
1809
|
+
initializer: ?Result = null,
|
|
1810
|
+
asm_label: ?Node.Index = null,
|
|
1811
|
+
};
|
|
1791
1812
|
|
|
1792
1813
|
/// attribute
|
|
1793
1814
|
/// : attrIdentifier
|
|
@@ -1829,18 +1850,18 @@ fn attribute(p: *Parser, kind: Attribute.Kind, namespace: ?[]const u8) Error!?Te
|
|
|
1829
1850
|
if (try p.eatIdentifier()) |ident| {
|
|
1830
1851
|
if (try Attribute.diagnoseIdent(attr, &arguments, ident, p)) {
|
|
1831
1852
|
p.skipTo(.r_paren);
|
|
1832
|
-
return
|
|
1853
|
+
return null;
|
|
1833
1854
|
}
|
|
1834
1855
|
} else {
|
|
1835
1856
|
try p.err(name_tok, .attribute_requires_identifier, .{name});
|
|
1836
|
-
return
|
|
1857
|
+
return null;
|
|
1837
1858
|
}
|
|
1838
1859
|
} else {
|
|
1839
1860
|
const arg_start = p.tok_i;
|
|
1840
1861
|
const first_expr = try p.expect(assignExpr);
|
|
1841
1862
|
if (try p.diagnose(attr, &arguments, arg_idx, first_expr, arg_start)) {
|
|
1842
1863
|
p.skipTo(.r_paren);
|
|
1843
|
-
return
|
|
1864
|
+
return null;
|
|
1844
1865
|
}
|
|
1845
1866
|
}
|
|
1846
1867
|
arg_idx += 1;
|
|
@@ -1851,7 +1872,7 @@ fn attribute(p: *Parser, kind: Attribute.Kind, namespace: ?[]const u8) Error!?Te
|
|
|
1851
1872
|
const arg_expr = try p.expect(assignExpr);
|
|
1852
1873
|
if (try p.diagnose(attr, &arguments, arg_idx, arg_expr, arg_start)) {
|
|
1853
1874
|
p.skipTo(.r_paren);
|
|
1854
|
-
return
|
|
1875
|
+
return null;
|
|
1855
1876
|
}
|
|
1856
1877
|
}
|
|
1857
1878
|
},
|
|
@@ -1861,9 +1882,9 @@ fn attribute(p: *Parser, kind: Attribute.Kind, namespace: ?[]const u8) Error!?Te
|
|
|
1861
1882
|
try p.err(name_tok, .attribute_not_enough_args, .{
|
|
1862
1883
|
@tagName(attr), required_count,
|
|
1863
1884
|
});
|
|
1864
|
-
return
|
|
1885
|
+
return null;
|
|
1865
1886
|
}
|
|
1866
|
-
return
|
|
1887
|
+
return .{ .attr = .{ .tag = attr, .args = arguments, .syntax = kind.toSyntax() }, .tok = name_tok };
|
|
1867
1888
|
}
|
|
1868
1889
|
|
|
1869
1890
|
fn diagnose(p: *Parser, attr: Attribute.Tag, arguments: *Attribute.Arguments, arg_idx: u32, res: Result, arg_start: TokenIndex) !bool {
|
|
@@ -1995,12 +2016,12 @@ fn initDeclarator(p: *Parser, decl_spec: *DeclSpec, attr_buf_top: usize, decl_no
|
|
|
1995
2016
|
defer p.attr_buf.len = this_attr_buf_top;
|
|
1996
2017
|
const gpa = p.comp.gpa;
|
|
1997
2018
|
|
|
1998
|
-
var init_d =
|
|
2019
|
+
var init_d: InitDeclarator = .{
|
|
1999
2020
|
.d = (try p.declarator(decl_spec.qt, .normal)) orelse return null,
|
|
2000
2021
|
};
|
|
2001
2022
|
|
|
2002
2023
|
try p.attributeSpecifierExtra(init_d.d.name);
|
|
2003
|
-
|
|
2024
|
+
init_d.asm_label = try p.assembly(.decl_label);
|
|
2004
2025
|
try p.attributeSpecifierExtra(init_d.d.name);
|
|
2005
2026
|
|
|
2006
2027
|
switch (init_d.d.declarator_type) {
|
|
@@ -2276,14 +2297,13 @@ fn typeSpec(p: *Parser, builder: *TypeStore.Builder) Error!bool {
|
|
|
2276
2297
|
}, .syntax = .keyword },
|
|
2277
2298
|
.tok = align_tok,
|
|
2278
2299
|
});
|
|
2279
|
-
} else {
|
|
2300
|
+
} else check: {
|
|
2280
2301
|
const arg_start = p.tok_i;
|
|
2281
2302
|
const res = try p.integerConstExpr(.no_const_decl_folding);
|
|
2282
2303
|
if (!res.val.isZero(p.comp)) {
|
|
2283
2304
|
var args = Attribute.initArguments(.aligned, align_tok);
|
|
2284
2305
|
if (try p.diagnose(.aligned, &args, 0, res, arg_start)) {
|
|
2285
|
-
|
|
2286
|
-
return error.ParsingFailed;
|
|
2306
|
+
break :check;
|
|
2287
2307
|
}
|
|
2288
2308
|
args.aligned.alignment.?.node = .pack(res.node);
|
|
2289
2309
|
try p.attr_buf.append(gpa, .{
|
|
@@ -2562,7 +2582,7 @@ fn recordSpec(p: *Parser) Error!QualType {
|
|
|
2562
2582
|
|
|
2563
2583
|
if (!any_incomplete) {
|
|
2564
2584
|
const pragma_pack_value = switch (p.comp.langopts.emulate) {
|
|
2565
|
-
.clang => starting_pragma_pack,
|
|
2585
|
+
.clang, .no => starting_pragma_pack,
|
|
2566
2586
|
.gcc => p.pragma_pack,
|
|
2567
2587
|
// TODO: msvc considers `#pragma pack` on a per-field basis
|
|
2568
2588
|
.msvc => p.pragma_pack,
|
|
@@ -3542,7 +3562,6 @@ fn declarator(
|
|
|
3542
3562
|
|
|
3543
3563
|
const pointer_qt = try p.comp.type_store.put(p.comp.gpa, .{ .pointer = .{
|
|
3544
3564
|
.child = d.qt,
|
|
3545
|
-
.decayed = null,
|
|
3546
3565
|
} });
|
|
3547
3566
|
d.qt = try builder.finishQuals(pointer_qt);
|
|
3548
3567
|
}
|
|
@@ -4141,7 +4160,10 @@ fn designation(p: *Parser, il: *InitList, init_qt: QualType, index_list: *IndexL
|
|
|
4141
4160
|
const field = record_ty.fields[field_index];
|
|
4142
4161
|
if (field.name_tok == 0) if (field.qt.getRecord(p.comp)) |field_record_ty| {
|
|
4143
4162
|
// Recurse into anonymous field if it has a field by the name.
|
|
4144
|
-
if (!field_record_ty.hasField(p.comp, target_name))
|
|
4163
|
+
if (!field_record_ty.hasField(p.comp, target_name)) {
|
|
4164
|
+
field_index += 1;
|
|
4165
|
+
continue;
|
|
4166
|
+
}
|
|
4145
4167
|
try index_list.append(gpa, field_index);
|
|
4146
4168
|
cur_il = try il.find(gpa, field_index);
|
|
4147
4169
|
record_ty = field_record_ty;
|
|
@@ -4818,8 +4840,9 @@ fn gnuAsmStmt(p: *Parser, quals: Tree.GNUAssemblyQualifiers, asm_tok: TokenIndex
|
|
|
4818
4840
|
const expected_items = 8; // arbitrarily chosen, most assembly will have fewer than 8 inputs/outputs/constraints/names
|
|
4819
4841
|
const bytes_needed = expected_items * @sizeOf(Tree.Node.AsmStmt.Operand) + expected_items * 2 * @sizeOf(Node.Index);
|
|
4820
4842
|
|
|
4821
|
-
var
|
|
4822
|
-
|
|
4843
|
+
var bfa_buf: [bytes_needed]u8 = undefined;
|
|
4844
|
+
var bfa: std.heap.BufferFirstAllocator = .init(&bfa_buf, gpa);
|
|
4845
|
+
const allocator = bfa.allocator();
|
|
4823
4846
|
|
|
4824
4847
|
var operands: std.ArrayList(Tree.Node.AsmStmt.Operand) = .empty;
|
|
4825
4848
|
defer operands.deinit(allocator);
|
|
@@ -4983,31 +5006,31 @@ fn assembly(p: *Parser, kind: enum { global, decl_label, stmt }) Error!?Node.Ind
|
|
|
4983
5006
|
};
|
|
4984
5007
|
|
|
4985
5008
|
const l_paren = try p.expectToken(.l_paren);
|
|
4986
|
-
|
|
4987
|
-
|
|
4988
|
-
.decl_label => {
|
|
5009
|
+
const res = switch (kind) {
|
|
5010
|
+
.decl_label => blk: {
|
|
4989
5011
|
const asm_str = try p.asmStr();
|
|
4990
5012
|
const str = try p.removeNull(asm_str.val);
|
|
4991
5013
|
|
|
4992
5014
|
const attr = Attribute{ .tag = .asm_label, .args = .{ .asm_label = .{ .name = str } }, .syntax = .keyword };
|
|
4993
5015
|
try p.attr_buf.append(p.comp.gpa, .{ .attr = attr, .tok = asm_tok });
|
|
5016
|
+
break :blk asm_str.node;
|
|
4994
5017
|
},
|
|
4995
|
-
.global => {
|
|
5018
|
+
.global => blk: {
|
|
4996
5019
|
const asm_str = try p.asmStr();
|
|
4997
5020
|
try p.checkAsmStr(asm_str.val, l_paren);
|
|
4998
|
-
|
|
5021
|
+
break :blk try p.addNode(.{
|
|
4999
5022
|
.global_asm = .{
|
|
5000
5023
|
.asm_tok = asm_tok,
|
|
5001
5024
|
.asm_str = asm_str.node,
|
|
5002
5025
|
},
|
|
5003
5026
|
});
|
|
5004
5027
|
},
|
|
5005
|
-
.stmt =>
|
|
5006
|
-
}
|
|
5028
|
+
.stmt => try p.gnuAsmStmt(quals, asm_tok, l_paren),
|
|
5029
|
+
};
|
|
5007
5030
|
try p.expectClosing(l_paren, .r_paren);
|
|
5008
5031
|
|
|
5009
5032
|
if (kind != .decl_label) _ = try p.expectToken(.semicolon);
|
|
5010
|
-
return
|
|
5033
|
+
return res;
|
|
5011
5034
|
}
|
|
5012
5035
|
|
|
5013
5036
|
/// Same as stringLiteral but errors on unicode and wide string literals
|
|
@@ -5253,7 +5276,6 @@ fn stmt(p: *Parser) Error!Node.Index {
|
|
|
5253
5276
|
if (!goto_expr.qt.isInvalid() and !goto_expr.qt.isPointer(p.comp)) {
|
|
5254
5277
|
const result_qt = try p.comp.type_store.put(gpa, .{ .pointer = .{
|
|
5255
5278
|
.child = .{ .@"const" = true, ._index = .void },
|
|
5256
|
-
.decayed = null,
|
|
5257
5279
|
} });
|
|
5258
5280
|
if (!goto_expr.qt.isRealInt(p.comp)) {
|
|
5259
5281
|
try p.err(expr_tok, .incompatible_arg, .{ goto_expr.qt, result_qt });
|
|
@@ -5703,9 +5725,8 @@ fn returnStmt(p: *Parser) Error!?Node.Index {
|
|
|
5703
5725
|
// ====== expressions ======
|
|
5704
5726
|
|
|
5705
5727
|
pub fn macroExpr(p: *Parser) Compilation.Error!bool {
|
|
5706
|
-
const res = p.expect(condExpr) catch |
|
|
5707
|
-
error.OutOfMemory => return
|
|
5708
|
-
error.FatalError => return error.FatalError,
|
|
5728
|
+
const res = p.expect(condExpr) catch |er| switch (er) {
|
|
5729
|
+
error.OutOfMemory, error.FatalError => |e| return e,
|
|
5709
5730
|
error.ParsingFailed => return false,
|
|
5710
5731
|
};
|
|
5711
5732
|
return res.val.toBool(p.comp);
|
|
@@ -5905,6 +5926,7 @@ const CallExpr = union(enum) {
|
|
|
5905
5926
|
.__builtin_reduce_xor,
|
|
5906
5927
|
.__builtin_reduce_max,
|
|
5907
5928
|
.__builtin_reduce_min,
|
|
5929
|
+
.__builtin_constant_p,
|
|
5908
5930
|
=> 1,
|
|
5909
5931
|
|
|
5910
5932
|
.__builtin_complex,
|
|
@@ -5922,13 +5944,15 @@ const CallExpr = union(enum) {
|
|
|
5922
5944
|
|
|
5923
5945
|
.__c11_atomic_store,
|
|
5924
5946
|
.__atomic_store,
|
|
5947
|
+
.__atomic_store_n,
|
|
5948
|
+
.__atomic_load,
|
|
5925
5949
|
.__c11_atomic_exchange,
|
|
5926
|
-
.__atomic_exchange,
|
|
5927
5950
|
.__c11_atomic_fetch_add,
|
|
5928
5951
|
.__c11_atomic_fetch_sub,
|
|
5929
5952
|
.__c11_atomic_fetch_or,
|
|
5930
5953
|
.__c11_atomic_fetch_xor,
|
|
5931
5954
|
.__c11_atomic_fetch_and,
|
|
5955
|
+
.__c11_atomic_fetch_nand,
|
|
5932
5956
|
.__atomic_fetch_add,
|
|
5933
5957
|
.__atomic_fetch_sub,
|
|
5934
5958
|
.__atomic_fetch_and,
|
|
@@ -5948,6 +5972,9 @@ const CallExpr = union(enum) {
|
|
|
5948
5972
|
.__atomic_exchange_n,
|
|
5949
5973
|
=> 3,
|
|
5950
5974
|
|
|
5975
|
+
.__atomic_exchange,
|
|
5976
|
+
=> 4,
|
|
5977
|
+
|
|
5951
5978
|
.__c11_atomic_compare_exchange_strong,
|
|
5952
5979
|
.__c11_atomic_compare_exchange_weak,
|
|
5953
5980
|
=> 5,
|
|
@@ -5964,25 +5991,13 @@ const CallExpr = union(enum) {
|
|
|
5964
5991
|
|
|
5965
5992
|
fn returnType(self: CallExpr, p: *Parser, args: []const Node.Index, func_qt: QualType) !QualType {
|
|
5966
5993
|
if (self == .standard) {
|
|
5994
|
+
if (func_qt.isInvalid()) return .invalid;
|
|
5967
5995
|
return if (func_qt.get(p.comp, .func)) |func_ty| func_ty.return_type else .invalid;
|
|
5968
5996
|
}
|
|
5969
5997
|
const builtin = self.builtin;
|
|
5970
5998
|
const func_ty = func_qt.get(p.comp, .func).?;
|
|
5971
5999
|
return switch (builtin.expanded.tag) {
|
|
5972
6000
|
.common => |tag| switch (tag) {
|
|
5973
|
-
.__c11_atomic_exchange => {
|
|
5974
|
-
if (args.len != 4) return .invalid; // wrong number of arguments; already an error
|
|
5975
|
-
const second_param = args[2];
|
|
5976
|
-
return second_param.qt(&p.tree);
|
|
5977
|
-
},
|
|
5978
|
-
.__c11_atomic_load => {
|
|
5979
|
-
if (args.len != 3) return .invalid; // wrong number of arguments; already an error
|
|
5980
|
-
const first_param = args[1];
|
|
5981
|
-
const qt = first_param.qt(&p.tree);
|
|
5982
|
-
if (!qt.isPointer(p.comp)) return .invalid;
|
|
5983
|
-
return qt.childType(p.comp);
|
|
5984
|
-
},
|
|
5985
|
-
|
|
5986
6001
|
.__atomic_fetch_add,
|
|
5987
6002
|
.__atomic_add_fetch,
|
|
5988
6003
|
.__c11_atomic_fetch_add,
|
|
@@ -6008,15 +6023,38 @@ const CallExpr = union(enum) {
|
|
|
6008
6023
|
.__c11_atomic_fetch_nand,
|
|
6009
6024
|
|
|
6010
6025
|
.__atomic_exchange_n,
|
|
6026
|
+
.__c11_atomic_exchange,
|
|
6027
|
+
=> {
|
|
6028
|
+
const second_param = args[1].qt(&p.tree);
|
|
6029
|
+
return second_param;
|
|
6030
|
+
},
|
|
6031
|
+
|
|
6032
|
+
.__sync_fetch_and_add,
|
|
6033
|
+
.__sync_fetch_and_and,
|
|
6034
|
+
.__sync_fetch_and_nand,
|
|
6035
|
+
.__sync_fetch_and_or,
|
|
6036
|
+
.__sync_fetch_and_sub,
|
|
6037
|
+
.__sync_fetch_and_xor,
|
|
6038
|
+
|
|
6039
|
+
.__sync_add_and_fetch,
|
|
6040
|
+
.__sync_and_and_fetch,
|
|
6041
|
+
.__sync_nand_and_fetch,
|
|
6042
|
+
.__sync_or_and_fetch,
|
|
6043
|
+
.__sync_sub_and_fetch,
|
|
6044
|
+
.__sync_xor_and_fetch,
|
|
6045
|
+
|
|
6046
|
+
.__sync_swap,
|
|
6047
|
+
.__sync_lock_test_and_set,
|
|
6048
|
+
.__sync_val_compare_and_swap,
|
|
6011
6049
|
=> {
|
|
6012
|
-
if (args.len
|
|
6013
|
-
const second_param = args[
|
|
6014
|
-
return second_param
|
|
6050
|
+
if (args.len < 2) return .invalid;
|
|
6051
|
+
const second_param = args[1].qt(&p.tree);
|
|
6052
|
+
return second_param;
|
|
6015
6053
|
},
|
|
6016
6054
|
.__builtin_complex => {
|
|
6017
|
-
|
|
6018
|
-
|
|
6019
|
-
return try last_param.
|
|
6055
|
+
const last_param = args[args.len - 1].qt(&p.tree);
|
|
6056
|
+
if (last_param.isInvalid()) return .invalid;
|
|
6057
|
+
return try last_param.toComplex(p.comp);
|
|
6020
6058
|
},
|
|
6021
6059
|
.__atomic_compare_exchange,
|
|
6022
6060
|
.__atomic_compare_exchange_n,
|
|
@@ -6027,9 +6065,8 @@ const CallExpr = union(enum) {
|
|
|
6027
6065
|
.__c11_atomic_compare_exchange_strong,
|
|
6028
6066
|
.__c11_atomic_compare_exchange_weak,
|
|
6029
6067
|
=> {
|
|
6030
|
-
|
|
6031
|
-
|
|
6032
|
-
return third_param.qt(&p.tree);
|
|
6068
|
+
const third_param = args[2].qt(&p.tree);
|
|
6069
|
+
return third_param;
|
|
6033
6070
|
},
|
|
6034
6071
|
|
|
6035
6072
|
.__builtin_elementwise_abs,
|
|
@@ -6058,13 +6095,12 @@ const CallExpr = union(enum) {
|
|
|
6058
6095
|
.__builtin_elementwise_sub_sat,
|
|
6059
6096
|
.__builtin_elementwise_fma,
|
|
6060
6097
|
.__builtin_elementwise_popcount,
|
|
6098
|
+
|
|
6061
6099
|
.__builtin_nondeterministic_value,
|
|
6062
6100
|
=> {
|
|
6063
|
-
|
|
6064
|
-
|
|
6065
|
-
return last_param.qt(&p.tree);
|
|
6101
|
+
const first_param = args[0].qt(&p.tree);
|
|
6102
|
+
return first_param;
|
|
6066
6103
|
},
|
|
6067
|
-
.__builtin_nontemporal_load,
|
|
6068
6104
|
.__builtin_reduce_add,
|
|
6069
6105
|
.__builtin_reduce_mul,
|
|
6070
6106
|
.__builtin_reduce_and,
|
|
@@ -6073,30 +6109,19 @@ const CallExpr = union(enum) {
|
|
|
6073
6109
|
.__builtin_reduce_max,
|
|
6074
6110
|
.__builtin_reduce_min,
|
|
6075
6111
|
=> {
|
|
6076
|
-
|
|
6077
|
-
|
|
6078
|
-
|
|
6112
|
+
const first_param = args[0].qt(&p.tree);
|
|
6113
|
+
if (first_param.isInvalid()) return .invalid;
|
|
6114
|
+
const vector_ty = first_param.get(p.comp, .vector) orelse return .invalid;
|
|
6115
|
+
return vector_ty.elem;
|
|
6079
6116
|
},
|
|
6080
|
-
.__sync_add_and_fetch,
|
|
6081
|
-
.__sync_and_and_fetch,
|
|
6082
|
-
.__sync_fetch_and_add,
|
|
6083
|
-
.__sync_fetch_and_and,
|
|
6084
|
-
.__sync_fetch_and_nand,
|
|
6085
|
-
.__sync_fetch_and_or,
|
|
6086
|
-
.__sync_fetch_and_sub,
|
|
6087
|
-
.__sync_fetch_and_xor,
|
|
6088
|
-
.__sync_lock_test_and_set,
|
|
6089
|
-
.__sync_nand_and_fetch,
|
|
6090
|
-
.__sync_or_and_fetch,
|
|
6091
|
-
.__sync_sub_and_fetch,
|
|
6092
|
-
.__sync_swap,
|
|
6093
|
-
.__sync_xor_and_fetch,
|
|
6094
|
-
.__sync_val_compare_and_swap,
|
|
6095
6117
|
.__atomic_load_n,
|
|
6118
|
+
.__c11_atomic_load,
|
|
6119
|
+
.__builtin_nontemporal_load,
|
|
6096
6120
|
=> {
|
|
6097
|
-
|
|
6098
|
-
|
|
6099
|
-
|
|
6121
|
+
const first_param = args[0].qt(&p.tree);
|
|
6122
|
+
if (first_param.isInvalid()) return .invalid;
|
|
6123
|
+
if (!first_param.isPointer(p.comp)) return .invalid;
|
|
6124
|
+
return first_param.childType(p.comp);
|
|
6100
6125
|
},
|
|
6101
6126
|
else => func_ty.return_type,
|
|
6102
6127
|
},
|
|
@@ -6104,9 +6129,16 @@ const CallExpr = union(enum) {
|
|
|
6104
6129
|
};
|
|
6105
6130
|
}
|
|
6106
6131
|
|
|
6107
|
-
fn finish(
|
|
6132
|
+
fn finish(
|
|
6133
|
+
self: CallExpr,
|
|
6134
|
+
p: *Parser,
|
|
6135
|
+
func_qt: QualType,
|
|
6136
|
+
list_buf_top: usize,
|
|
6137
|
+
l_paren: TokenIndex,
|
|
6138
|
+
args_ok: bool,
|
|
6139
|
+
) Error!Result {
|
|
6108
6140
|
const args = p.list_buf.items[list_buf_top..];
|
|
6109
|
-
const return_qt = try self.returnType(p, args, func_qt);
|
|
6141
|
+
const return_qt: QualType = if (args_ok) try self.returnType(p, args, func_qt) else .invalid;
|
|
6110
6142
|
switch (self) {
|
|
6111
6143
|
.standard => |func_node| return .{
|
|
6112
6144
|
.qt = return_qt,
|
|
@@ -6118,7 +6150,7 @@ const CallExpr = union(enum) {
|
|
|
6118
6150
|
} }),
|
|
6119
6151
|
},
|
|
6120
6152
|
.builtin => |builtin| return .{
|
|
6121
|
-
.val = try evalBuiltin(builtin.expanded, p, args),
|
|
6153
|
+
.val = if (args_ok) try evalBuiltin(builtin.expanded, p, args) else .{},
|
|
6122
6154
|
.qt = return_qt,
|
|
6123
6155
|
.node = try p.addNode(.{ .builtin_call_expr = .{
|
|
6124
6156
|
.builtin_tok = builtin.builtin_tok,
|
|
@@ -6283,14 +6315,12 @@ pub const Result = struct {
|
|
|
6283
6315
|
if (!adjusted_elem_qt.eqlQualified(a_elem, p.comp)) {
|
|
6284
6316
|
a.qt = try p.comp.type_store.put(gpa, .{ .pointer = .{
|
|
6285
6317
|
.child = adjusted_elem_qt,
|
|
6286
|
-
.decayed = null,
|
|
6287
6318
|
} });
|
|
6288
6319
|
try a.implicitCast(p, .bitcast, tok);
|
|
6289
6320
|
}
|
|
6290
6321
|
if (!adjusted_elem_qt.eqlQualified(b_elem, p.comp)) {
|
|
6291
6322
|
b.qt = try p.comp.type_store.put(gpa, .{ .pointer = .{
|
|
6292
6323
|
.child = adjusted_elem_qt,
|
|
6293
|
-
.decayed = null,
|
|
6294
6324
|
} });
|
|
6295
6325
|
try b.implicitCast(p, .bitcast, tok);
|
|
6296
6326
|
}
|
|
@@ -6478,6 +6508,7 @@ pub const Result = struct {
|
|
|
6478
6508
|
.add => {
|
|
6479
6509
|
// if both aren't arithmetic one should be pointer and the other an integer
|
|
6480
6510
|
if (a_sk.isPointer() == b_sk.isPointer() or a_sk.isInt() == b_sk.isInt()) return a.invalidBinTy(tok, b, p);
|
|
6511
|
+
try p.boundsSafetyCheckPointerArithmetic(a.qt, b.qt, tok, a.node);
|
|
6481
6512
|
|
|
6482
6513
|
if (a_sk == .void_pointer or b_sk == .void_pointer)
|
|
6483
6514
|
try p.err(tok, .gnu_pointer_arith, .{});
|
|
@@ -6496,6 +6527,7 @@ pub const Result = struct {
|
|
|
6496
6527
|
.sub => {
|
|
6497
6528
|
// if both aren't arithmetic then either both should be pointers or just the left one.
|
|
6498
6529
|
if (!a_sk.isPointer() or !(b_sk.isPointer() or b_sk.isInt())) return a.invalidBinTy(tok, b, p);
|
|
6530
|
+
try p.boundsSafetyCheckPointerArithmetic(a.qt, b.qt, tok, a.node);
|
|
6499
6531
|
|
|
6500
6532
|
if (a_sk == .void_pointer)
|
|
6501
6533
|
try p.err(tok, .gnu_pointer_arith, .{});
|
|
@@ -7087,14 +7119,14 @@ pub const Result = struct {
|
|
|
7087
7119
|
} else if (dest_sk.isPointer()) {
|
|
7088
7120
|
if (src_sk.isPointer()) {
|
|
7089
7121
|
cast_kind = .bitcast;
|
|
7122
|
+
} else if (src_sk == .bool) {
|
|
7123
|
+
cast_kind = .bool_to_pointer;
|
|
7090
7124
|
} else if (src_sk.isInt()) {
|
|
7091
7125
|
if (!src_sk.isReal()) {
|
|
7092
7126
|
res.qt = res.qt.toReal(p.comp);
|
|
7093
7127
|
try res.implicitCast(p, .complex_int_to_real, l_paren);
|
|
7094
7128
|
}
|
|
7095
7129
|
cast_kind = .int_to_pointer;
|
|
7096
|
-
} else if (src_sk == .bool) {
|
|
7097
|
-
cast_kind = .bool_to_pointer;
|
|
7098
7130
|
} else if (res.qt.is(p.comp, .array)) {
|
|
7099
7131
|
cast_kind = .array_to_pointer;
|
|
7100
7132
|
} else if (res.qt.is(p.comp, .func)) {
|
|
@@ -7497,7 +7529,16 @@ fn issueDeclaredConstHereNote(p: *Parser, decl_ref: Tree.Node.DeclRef, var_name:
|
|
|
7497
7529
|
try p.err(location, .declared_const_here, .{var_name});
|
|
7498
7530
|
}
|
|
7499
7531
|
|
|
7500
|
-
fn
|
|
7532
|
+
fn issueBoundsDeclaredHereNote(p: *Parser, decl_ref: Tree.Node.DeclRef, var_name: []const u8, bounds: Type.Pointer.Bounds) Compilation.Error!void {
|
|
7533
|
+
const location = switch (decl_ref.decl.get(&p.tree)) {
|
|
7534
|
+
.variable => |variable| variable.name_tok,
|
|
7535
|
+
.param => |param| param.name_tok,
|
|
7536
|
+
else => return,
|
|
7537
|
+
};
|
|
7538
|
+
try p.err(location, .pointer_bounds_declared_here, .{ var_name, @tagName(bounds) });
|
|
7539
|
+
}
|
|
7540
|
+
|
|
7541
|
+
fn issueConstAssignmentDiagnostics(p: *Parser, node_idx: Node.Index, tok: TokenIndex) Compilation.Error!void {
|
|
7501
7542
|
if (p.unwrapNestedOperation(node_idx)) |unwrapped| {
|
|
7502
7543
|
const name = p.tokSlice(unwrapped.name_tok);
|
|
7503
7544
|
try p.err(tok, .const_var_assignment, .{ name, unwrapped.qt });
|
|
@@ -7530,7 +7571,7 @@ fn assignExpr(p: *Parser) Error!?Result {
|
|
|
7530
7571
|
|
|
7531
7572
|
var is_const: bool = undefined;
|
|
7532
7573
|
if (!p.tree.isLvalExtra(lhs.node, &is_const) or is_const) {
|
|
7533
|
-
try p.
|
|
7574
|
+
try p.issueConstAssignmentDiagnostics(lhs.node, tok);
|
|
7534
7575
|
lhs.qt = .invalid;
|
|
7535
7576
|
}
|
|
7536
7577
|
|
|
@@ -8226,7 +8267,7 @@ fn builtinChooseExpr(p: *Parser) Error!Result {
|
|
|
8226
8267
|
return cond;
|
|
8227
8268
|
}
|
|
8228
8269
|
|
|
8229
|
-
///
|
|
8270
|
+
/// vaArg : __builtin_va_arg '(' assignExpr ',' typeName ')'
|
|
8230
8271
|
fn builtinVaArg(p: *Parser, builtin_tok: TokenIndex) Error!Result {
|
|
8231
8272
|
const l_paren = try p.expectToken(.l_paren);
|
|
8232
8273
|
const va_list_tok = p.tok_i;
|
|
@@ -8258,6 +8299,62 @@ fn builtinVaArg(p: *Parser, builtin_tok: TokenIndex) Error!Result {
|
|
|
8258
8299
|
};
|
|
8259
8300
|
}
|
|
8260
8301
|
|
|
8302
|
+
/// vaArgPack : __builtin_va_arg_pack '(' ')'
|
|
8303
|
+
fn builtinVaArgPack(p: *Parser, builtin_tok: TokenIndex) Error!Result {
|
|
8304
|
+
const l_paren = try p.expectToken(.l_paren);
|
|
8305
|
+
try p.expectClosing(l_paren, .r_paren);
|
|
8306
|
+
|
|
8307
|
+
var res_qt: QualType = .invalid;
|
|
8308
|
+
if (!try p.checkVaPackFunc(builtin_tok, "__builtin_va_arg_pack")) {
|
|
8309
|
+
// Only add one error.
|
|
8310
|
+
} else if (!p.va_arg_pack_ctx.valid) {
|
|
8311
|
+
try p.err(builtin_tok, .va_pack_non_call, .{});
|
|
8312
|
+
} else if (!p.va_arg_pack_ctx.variadic) {
|
|
8313
|
+
try p.err(builtin_tok, .va_pack_non_variadic_call, .{});
|
|
8314
|
+
} else if (p.va_arg_pack_ctx.typed) {
|
|
8315
|
+
try p.err(builtin_tok, .va_pack_non_variadic_arg, .{});
|
|
8316
|
+
} else {
|
|
8317
|
+
res_qt = .void;
|
|
8318
|
+
}
|
|
8319
|
+
return .{
|
|
8320
|
+
.qt = res_qt,
|
|
8321
|
+
.node = try p.addNode(.{
|
|
8322
|
+
.builtin_va_arg_pack = .{ .builtin_tok = builtin_tok },
|
|
8323
|
+
}),
|
|
8324
|
+
};
|
|
8325
|
+
}
|
|
8326
|
+
|
|
8327
|
+
/// vaArgPackLen : __builtin_va_arg_pack_len '(' ')'
|
|
8328
|
+
fn builtinVaArgPackLen(p: *Parser, builtin_tok: TokenIndex) Error!Result {
|
|
8329
|
+
const l_paren = try p.expectToken(.l_paren);
|
|
8330
|
+
try p.expectClosing(l_paren, .r_paren);
|
|
8331
|
+
|
|
8332
|
+
_ = try p.checkVaPackFunc(builtin_tok, "__builtin_va_arg_pack_len");
|
|
8333
|
+
|
|
8334
|
+
return .{
|
|
8335
|
+
.qt = .int,
|
|
8336
|
+
.node = try p.addNode(.{
|
|
8337
|
+
.builtin_va_arg_pack_len = .{
|
|
8338
|
+
.builtin_tok = builtin_tok,
|
|
8339
|
+
},
|
|
8340
|
+
}),
|
|
8341
|
+
};
|
|
8342
|
+
}
|
|
8343
|
+
|
|
8344
|
+
fn checkVaPackFunc(p: *Parser, builtin_tok: TokenIndex, va_func_name: []const u8) !bool {
|
|
8345
|
+
const func_qt, _ = (try p.checkVaFunc(builtin_tok, va_func_name)) orelse return false;
|
|
8346
|
+
|
|
8347
|
+
var it = Attribute.Iterator.initType(func_qt, p.comp);
|
|
8348
|
+
while (it.next()) |item| switch (item[0].tag) {
|
|
8349
|
+
.always_inline, .gnu_inline => break,
|
|
8350
|
+
else => {},
|
|
8351
|
+
} else {
|
|
8352
|
+
try p.err(builtin_tok, .va_func_not_always_inline, .{va_func_name});
|
|
8353
|
+
return false;
|
|
8354
|
+
}
|
|
8355
|
+
return true;
|
|
8356
|
+
}
|
|
8357
|
+
|
|
8261
8358
|
const OffsetKind = enum { bits, bytes };
|
|
8262
8359
|
|
|
8263
8360
|
/// offsetof
|
|
@@ -8504,7 +8601,6 @@ fn unExpr(p: *Parser) Error!?Result {
|
|
|
8504
8601
|
|
|
8505
8602
|
operand.qt = try p.comp.type_store.put(gpa, .{ .pointer = .{
|
|
8506
8603
|
.child = operand.qt,
|
|
8507
|
-
.decayed = null,
|
|
8508
8604
|
} });
|
|
8509
8605
|
}
|
|
8510
8606
|
if (p.getNode(operand.node, .decl_ref_expr)) |decl_ref| {
|
|
@@ -8596,6 +8692,9 @@ fn unExpr(p: *Parser) Error!?Result {
|
|
|
8596
8692
|
try p.err(tok, .not_assignable, .{});
|
|
8597
8693
|
return error.ParsingFailed;
|
|
8598
8694
|
}
|
|
8695
|
+
if (operand.qt.get(p.comp, .pointer)) |pointer| {
|
|
8696
|
+
try p.checkPtrArithmeticAllowed(pointer, p.tok_i, operand.node);
|
|
8697
|
+
}
|
|
8599
8698
|
try operand.usualUnaryConversion(p, tok);
|
|
8600
8699
|
|
|
8601
8700
|
if (operand.val.is(.int, p.comp) or operand.val.is(.int, p.comp)) {
|
|
@@ -8624,6 +8723,9 @@ fn unExpr(p: *Parser) Error!?Result {
|
|
|
8624
8723
|
try p.err(tok, .not_assignable, .{});
|
|
8625
8724
|
return error.ParsingFailed;
|
|
8626
8725
|
}
|
|
8726
|
+
if (operand.qt.get(p.comp, .pointer)) |pointer| {
|
|
8727
|
+
try p.checkPtrArithmeticAllowed(pointer, p.tok_i, operand.node);
|
|
8728
|
+
}
|
|
8627
8729
|
try operand.usualUnaryConversion(p, tok);
|
|
8628
8730
|
|
|
8629
8731
|
if (operand.val.is(.int, p.comp) or operand.val.is(.int, p.comp)) {
|
|
@@ -8826,7 +8928,7 @@ fn unExpr(p: *Parser) Error!?Result {
|
|
|
8826
8928
|
} else switch (p.comp.langopts.emulate) {
|
|
8827
8929
|
.msvc => {}, // Doesn't support `_Complex` or `__imag` in the first place
|
|
8828
8930
|
.gcc => operand.val = .zero,
|
|
8829
|
-
.clang => {
|
|
8931
|
+
.clang, .no => {
|
|
8830
8932
|
if (operand.val.is(.int, p.comp) or operand.val.is(.float, p.comp)) {
|
|
8831
8933
|
operand.val = .zero;
|
|
8832
8934
|
} else {
|
|
@@ -8886,7 +8988,7 @@ fn compoundLiteral(p: *Parser, qt_opt: ?QualType, opt_l_paren: ?TokenIndex) Erro
|
|
|
8886
8988
|
try p.err(tok, .invalid_compound_literal_storage_class, .{@tagName(d.storage_class)});
|
|
8887
8989
|
d.storage_class = .none;
|
|
8888
8990
|
},
|
|
8889
|
-
.register => if (p.func.qt == null) try p.err(p.tok_i, .
|
|
8991
|
+
.register => if (p.func.qt == null) try p.err(p.tok_i, .register_on_global_compound_literal, .{}),
|
|
8890
8992
|
else => {},
|
|
8891
8993
|
}
|
|
8892
8994
|
|
|
@@ -8968,6 +9070,9 @@ fn suffixExpr(p: *Parser, lhs: Result) Error!?Result {
|
|
|
8968
9070
|
try p.err(p.tok_i, .not_assignable, .{});
|
|
8969
9071
|
return error.ParsingFailed;
|
|
8970
9072
|
}
|
|
9073
|
+
if (operand.qt.get(p.comp, .pointer)) |pointer| {
|
|
9074
|
+
try p.checkPtrArithmeticAllowed(pointer, p.tok_i, operand.node);
|
|
9075
|
+
}
|
|
8971
9076
|
try operand.usualUnaryConversion(p, p.tok_i);
|
|
8972
9077
|
|
|
8973
9078
|
try operand.un(p, .post_inc_expr, p.tok_i);
|
|
@@ -8989,6 +9094,9 @@ fn suffixExpr(p: *Parser, lhs: Result) Error!?Result {
|
|
|
8989
9094
|
try p.err(p.tok_i, .not_assignable, .{});
|
|
8990
9095
|
return error.ParsingFailed;
|
|
8991
9096
|
}
|
|
9097
|
+
if (operand.qt.get(p.comp, .pointer)) |pointer| {
|
|
9098
|
+
try p.checkPtrArithmeticAllowed(pointer, p.tok_i, operand.node);
|
|
9099
|
+
}
|
|
8992
9100
|
try operand.usualUnaryConversion(p, p.tok_i);
|
|
8993
9101
|
|
|
8994
9102
|
try operand.un(p, .post_dec_expr, p.tok_i);
|
|
@@ -9003,6 +9111,7 @@ fn suffixExpr(p: *Parser, lhs: Result) Error!?Result {
|
|
|
9003
9111
|
const array_before_conversion = lhs;
|
|
9004
9112
|
const index_before_conversion = index;
|
|
9005
9113
|
var ptr = lhs;
|
|
9114
|
+
|
|
9006
9115
|
try ptr.lvalConversion(p, l_bracket);
|
|
9007
9116
|
try index.lvalConversion(p, l_bracket);
|
|
9008
9117
|
if (ptr.qt.get(p.comp, .pointer)) |pointer_ty| {
|
|
@@ -9176,14 +9285,7 @@ fn checkVaStartArg(p: *Parser, builtin_tok: TokenIndex, first_after: TokenIndex,
|
|
|
9176
9285
|
return error.ParsingFailed;
|
|
9177
9286
|
}
|
|
9178
9287
|
|
|
9179
|
-
const
|
|
9180
|
-
try p.err(builtin_tok, .va_start_not_in_func, .{});
|
|
9181
|
-
return;
|
|
9182
|
-
};
|
|
9183
|
-
const func_ty = func_qt.get(p.comp, .func) orelse return;
|
|
9184
|
-
if (func_ty.kind != .variadic or func_ty.params.len == 0) {
|
|
9185
|
-
return p.err(builtin_tok, .va_start_fixed_args, .{});
|
|
9186
|
-
}
|
|
9288
|
+
_, const func_ty = (try p.checkVaFunc(builtin_tok, "va_start")) orelse return;
|
|
9187
9289
|
const last_param_name = func_ty.params[func_ty.params.len - 1].name;
|
|
9188
9290
|
const decl_ref = p.getNode(arg.node, .decl_ref_expr);
|
|
9189
9291
|
if (decl_ref == null or last_param_name != try p.comp.internString(p.tokSlice(decl_ref.?.name_tok))) {
|
|
@@ -9191,6 +9293,19 @@ fn checkVaStartArg(p: *Parser, builtin_tok: TokenIndex, first_after: TokenIndex,
|
|
|
9191
9293
|
}
|
|
9192
9294
|
}
|
|
9193
9295
|
|
|
9296
|
+
fn checkVaFunc(p: *Parser, builtin_tok: TokenIndex, va_func_name: []const u8) !?struct { QualType, Type.Func } {
|
|
9297
|
+
const func_qt = p.func.qt orelse {
|
|
9298
|
+
try p.err(builtin_tok, .va_func_not_in_func, .{va_func_name});
|
|
9299
|
+
return null;
|
|
9300
|
+
};
|
|
9301
|
+
const func_ty = func_qt.get(p.comp, .func) orelse return null;
|
|
9302
|
+
if (func_ty.kind != .variadic or func_ty.params.len == 0) {
|
|
9303
|
+
try p.err(builtin_tok, .va_func_fixed_args, .{va_func_name});
|
|
9304
|
+
return null;
|
|
9305
|
+
}
|
|
9306
|
+
return .{ func_qt, func_ty };
|
|
9307
|
+
}
|
|
9308
|
+
|
|
9194
9309
|
fn checkArithOverflowArg(p: *Parser, builtin_tok: TokenIndex, first_after: TokenIndex, param_tok: TokenIndex, arg: *Result, idx: u32) !void {
|
|
9195
9310
|
_ = builtin_tok;
|
|
9196
9311
|
_ = first_after;
|
|
@@ -9320,7 +9435,7 @@ fn callExpr(p: *Parser, lhs: Result) Error!Result {
|
|
|
9320
9435
|
|
|
9321
9436
|
// We cannot refer to the function type here because the pointer to
|
|
9322
9437
|
// type_store.extra might get invalidated while parsing args.
|
|
9323
|
-
const func_qt, const
|
|
9438
|
+
const func_qt, const typed_params_len, const func_kind_base = blk: {
|
|
9324
9439
|
var base_qt = lhs.qt;
|
|
9325
9440
|
if (base_qt.get(p.comp, .pointer)) |pointer_ty| base_qt = pointer_ty.child;
|
|
9326
9441
|
if (base_qt.isInvalid()) break :blk .{ base_qt, std.math.maxInt(usize), undefined };
|
|
@@ -9343,9 +9458,44 @@ fn callExpr(p: *Parser, lhs: Result) Error!Result {
|
|
|
9343
9458
|
|
|
9344
9459
|
const call_expr = CallExpr.init(p, lhs.node, func.node);
|
|
9345
9460
|
|
|
9461
|
+
const param_len_override = call_expr.paramCountOverride();
|
|
9462
|
+
const params_len = param_len_override orelse typed_params_len;
|
|
9463
|
+
const func_kind = if (param_len_override != null) .normal else func_kind_base;
|
|
9464
|
+
|
|
9346
9465
|
while (p.eatToken(.r_paren) == null) {
|
|
9347
9466
|
const param_tok = p.tok_i;
|
|
9348
9467
|
if (arg_count == params_len) first_after = p.tok_i;
|
|
9468
|
+
|
|
9469
|
+
// Check for __builtin_va_arg_pack
|
|
9470
|
+
{
|
|
9471
|
+
var i = p.tok_i;
|
|
9472
|
+
loop: switch (p.tok_ids[i]) {
|
|
9473
|
+
.l_paren => {
|
|
9474
|
+
i += 1;
|
|
9475
|
+
continue :loop p.tok_ids[i];
|
|
9476
|
+
},
|
|
9477
|
+
.identifier => if (mem.eql(u8, p.tokSlice(i), "__builtin_va_arg_pack")) {
|
|
9478
|
+
@branchHint(.cold);
|
|
9479
|
+
p.va_arg_pack_ctx = .{
|
|
9480
|
+
.valid = true,
|
|
9481
|
+
.variadic = func_kind != .normal,
|
|
9482
|
+
.typed = arg_count < typed_params_len,
|
|
9483
|
+
};
|
|
9484
|
+
defer p.va_arg_pack_ctx = .{};
|
|
9485
|
+
|
|
9486
|
+
const arg = try p.expect(assignExpr);
|
|
9487
|
+
try p.list_buf.append(gpa, arg.node);
|
|
9488
|
+
arg_count += 1;
|
|
9489
|
+
if (p.eatToken(.comma)) |_| {
|
|
9490
|
+
try p.err(i, .va_pack_non_final_arg, .{});
|
|
9491
|
+
continue;
|
|
9492
|
+
}
|
|
9493
|
+
try p.expectClosing(l_paren, .r_paren);
|
|
9494
|
+
break;
|
|
9495
|
+
},
|
|
9496
|
+
else => {},
|
|
9497
|
+
}
|
|
9498
|
+
}
|
|
9349
9499
|
var arg = try p.expect(assignExpr);
|
|
9350
9500
|
|
|
9351
9501
|
if (call_expr.shouldPerformLvalConversion(arg_count)) {
|
|
@@ -9353,7 +9503,7 @@ fn callExpr(p: *Parser, lhs: Result) Error!Result {
|
|
|
9353
9503
|
}
|
|
9354
9504
|
if ((arg.qt.hasIncompleteSize(p.comp) and !arg.qt.is(p.comp, .void)) or arg.qt.isInvalid()) return error.ParsingFailed;
|
|
9355
9505
|
|
|
9356
|
-
if (arg_count >=
|
|
9506
|
+
if (arg_count >= typed_params_len) {
|
|
9357
9507
|
if (call_expr.shouldPromoteVarArg(arg_count)) switch (arg.qt.base(p.comp).type) {
|
|
9358
9508
|
.int => |int_ty| if (int_ty == .int) try arg.castToInt(p, arg.qt.promoteInt(p.comp), param_tok),
|
|
9359
9509
|
.float => |float_ty| if (float_ty == .double) try arg.castToFloat(p, .double, param_tok),
|
|
@@ -9407,19 +9557,23 @@ fn callExpr(p: *Parser, lhs: Result) Error!Result {
|
|
|
9407
9557
|
}
|
|
9408
9558
|
if (func_qt.isInvalid()) {
|
|
9409
9559
|
// Skip argument count checks.
|
|
9410
|
-
return try call_expr.finish(p, func_qt, list_buf_top, l_paren);
|
|
9560
|
+
return try call_expr.finish(p, func_qt, list_buf_top, l_paren, false);
|
|
9411
9561
|
}
|
|
9412
9562
|
|
|
9413
|
-
|
|
9414
|
-
|
|
9415
|
-
|
|
9416
|
-
}
|
|
9417
|
-
} else switch (func_kind) {
|
|
9563
|
+
const r_paren = p.tok_i - 1;
|
|
9564
|
+
var args_ok = true;
|
|
9565
|
+
switch (func_kind) {
|
|
9418
9566
|
.normal => if (params_len != arg_count) {
|
|
9419
|
-
try p.err(
|
|
9567
|
+
try p.err(
|
|
9568
|
+
if (arg_count < params_len) r_paren else first_after,
|
|
9569
|
+
.expected_arguments,
|
|
9570
|
+
.{ params_len, arg_count },
|
|
9571
|
+
);
|
|
9572
|
+
args_ok = false;
|
|
9420
9573
|
},
|
|
9421
9574
|
.variadic => if (arg_count < params_len) {
|
|
9422
|
-
try p.err(
|
|
9575
|
+
try p.err(r_paren, .expected_at_least_arguments, .{ params_len, arg_count });
|
|
9576
|
+
args_ok = false;
|
|
9423
9577
|
},
|
|
9424
9578
|
.old_style => if (params_len != arg_count) {
|
|
9425
9579
|
if (params_len == 0)
|
|
@@ -9429,10 +9583,60 @@ fn callExpr(p: *Parser, lhs: Result) Error!Result {
|
|
|
9429
9583
|
},
|
|
9430
9584
|
}
|
|
9431
9585
|
|
|
9432
|
-
return try call_expr.finish(p, func_qt, list_buf_top, l_paren);
|
|
9586
|
+
return try call_expr.finish(p, func_qt, list_buf_top, l_paren, args_ok);
|
|
9587
|
+
}
|
|
9588
|
+
|
|
9589
|
+
fn boundsSafetyCheckArrayAccess(p: *Parser, lhs: Result, rhs: Result, l_bracket: TokenIndex) !void {
|
|
9590
|
+
if (!p.comp.hasClangStyleBoundsSafety()) return;
|
|
9591
|
+
|
|
9592
|
+
const ptr_res, const pointer, const index = if (lhs.qt.get(p.comp, .pointer)) |pointer| .{ lhs, pointer, rhs } else .{ rhs, rhs.qt.get(p.comp, .pointer).?, lhs };
|
|
9593
|
+
|
|
9594
|
+
switch (pointer.bounds) {
|
|
9595
|
+
.c, .unsafe_indexable => {},
|
|
9596
|
+
.single => {
|
|
9597
|
+
if (!index.val.isZero(p.comp)) {
|
|
9598
|
+
try p.err(l_bracket, .single_requires_zero_index, .{});
|
|
9599
|
+
if (p.unwrapNestedOperation(ptr_res.node)) |unwrapped| {
|
|
9600
|
+
const name = p.tokSlice(unwrapped.name_tok);
|
|
9601
|
+
try p.issueBoundsDeclaredHereNote(unwrapped, name, pointer.bounds);
|
|
9602
|
+
}
|
|
9603
|
+
}
|
|
9604
|
+
},
|
|
9605
|
+
}
|
|
9606
|
+
}
|
|
9607
|
+
|
|
9608
|
+
fn boundsSafetyCheckPointerArithmetic(p: *Parser, lhs: QualType, rhs: QualType, tok: TokenIndex, node: Tree.Node.Index) !void {
|
|
9609
|
+
if (!p.comp.hasClangStyleBoundsSafety()) return;
|
|
9610
|
+
|
|
9611
|
+
const pointer = if (rhs.isInt(p.comp))
|
|
9612
|
+
lhs.get(p.comp, .pointer) orelse return
|
|
9613
|
+
else if (lhs.isInt(p.comp))
|
|
9614
|
+
rhs.get(p.comp, .pointer) orelse return
|
|
9615
|
+
else
|
|
9616
|
+
return;
|
|
9617
|
+
|
|
9618
|
+
try p.checkPtrArithmeticAllowed(pointer, tok, node);
|
|
9619
|
+
}
|
|
9620
|
+
|
|
9621
|
+
fn checkPtrArithmeticAllowed(p: *Parser, pointer: Type.Pointer, tok: TokenIndex, node: Tree.Node.Index) !void {
|
|
9622
|
+
if (!p.comp.hasClangStyleBoundsSafety()) return;
|
|
9623
|
+
|
|
9624
|
+
switch (pointer.bounds) {
|
|
9625
|
+
.c, .unsafe_indexable => {},
|
|
9626
|
+
.single => {
|
|
9627
|
+
// clang issues this diagnostic even with a constant `0` operand
|
|
9628
|
+
try p.err(tok, .pointer_arith_single, .{});
|
|
9629
|
+
if (p.unwrapNestedOperation(node)) |unwrapped| {
|
|
9630
|
+
const name = p.tokSlice(unwrapped.name_tok);
|
|
9631
|
+
try p.issueBoundsDeclaredHereNote(unwrapped, name, pointer.bounds);
|
|
9632
|
+
}
|
|
9633
|
+
},
|
|
9634
|
+
}
|
|
9433
9635
|
}
|
|
9434
9636
|
|
|
9435
9637
|
fn checkArrayBounds(p: *Parser, index: Result, array: Result, tok: TokenIndex) !void {
|
|
9638
|
+
try p.boundsSafetyCheckArrayAccess(array, index, tok);
|
|
9639
|
+
|
|
9436
9640
|
if (index.val.opt_ref == .none) return;
|
|
9437
9641
|
|
|
9438
9642
|
const array_len = array.qt.arrayLen(p.comp) orelse return;
|
|
@@ -9579,6 +9783,8 @@ fn primaryExpr(p: *Parser) Error!?Result {
|
|
|
9579
9783
|
.common => |tag| switch (tag) {
|
|
9580
9784
|
.__builtin_choose_expr => return try p.builtinChooseExpr(),
|
|
9581
9785
|
.__builtin_va_arg => return try p.builtinVaArg(name_tok),
|
|
9786
|
+
.__builtin_va_arg_pack => return try p.builtinVaArgPack(name_tok),
|
|
9787
|
+
.__builtin_va_arg_pack_len => return try p.builtinVaArgPackLen(name_tok),
|
|
9582
9788
|
.__builtin_offsetof => return try p.builtinOffsetof(name_tok, .bytes),
|
|
9583
9789
|
.__builtin_bitoffsetof => return try p.builtinOffsetof(name_tok, .bits),
|
|
9584
9790
|
.__builtin_types_compatible_p => return try p.typesCompatible(name_tok),
|
|
@@ -9719,8 +9925,9 @@ fn primaryExpr(p: *Parser) Error!?Result {
|
|
|
9719
9925
|
if (p.func.pretty_ident) |some| {
|
|
9720
9926
|
qt = some.qt;
|
|
9721
9927
|
} else if (p.func.qt) |func_qt| {
|
|
9722
|
-
var
|
|
9723
|
-
var
|
|
9928
|
+
var bfa_buf: [1024]u8 = undefined;
|
|
9929
|
+
var bfa: std.heap.BufferFirstAllocator = .init(&bfa_buf, gpa);
|
|
9930
|
+
var allocating: std.Io.Writer.Allocating = .init(bfa.allocator());
|
|
9724
9931
|
defer allocating.deinit();
|
|
9725
9932
|
|
|
9726
9933
|
func_qt.printNamed(p.tokSlice(p.func.name), p.comp, &allocating.writer) catch return error.OutOfMemory;
|
|
@@ -10009,8 +10216,9 @@ fn charLiteral(p: *Parser) Error!?Result {
|
|
|
10009
10216
|
};
|
|
10010
10217
|
|
|
10011
10218
|
const max_chars_expected = 4;
|
|
10012
|
-
var
|
|
10013
|
-
|
|
10219
|
+
var bfa_buf: [max_chars_expected]u32 = undefined;
|
|
10220
|
+
var bfa: std.heap.BufferFirstAllocator = .init(@ptrCast(&bfa_buf), gpa);
|
|
10221
|
+
const allocator = bfa.allocator();
|
|
10014
10222
|
var chars: std.ArrayList(u32) = .empty;
|
|
10015
10223
|
defer chars.deinit(allocator);
|
|
10016
10224
|
|
|
@@ -10277,16 +10485,13 @@ fn fixedSizeInt(p: *Parser, base: u8, buf: []const u8, suffix: NumberSuffix, tok
|
|
|
10277
10485
|
if (res.qt.intRankOrder(suffix_qt, p.comp).compare(.lt)) continue;
|
|
10278
10486
|
const max_int = try Value.maxInt(res.qt, p.comp);
|
|
10279
10487
|
if (interned_val.compare(.lte, max_int, p.comp)) break;
|
|
10280
|
-
} else {
|
|
10281
|
-
if (p.comp.
|
|
10282
|
-
|
|
10283
|
-
res.qt = .int128;
|
|
10284
|
-
} else {
|
|
10285
|
-
res.qt = .long_long;
|
|
10286
|
-
}
|
|
10488
|
+
} else switch (p.comp.langopts.emulate) {
|
|
10489
|
+
.no, .gcc => if (p.comp.target.hasInt128()) {
|
|
10490
|
+
res.qt = .int128;
|
|
10287
10491
|
} else {
|
|
10288
|
-
res.qt = .
|
|
10289
|
-
}
|
|
10492
|
+
res.qt = .long_long;
|
|
10493
|
+
},
|
|
10494
|
+
.msvc, .clang => res.qt = .ulong_long,
|
|
10290
10495
|
}
|
|
10291
10496
|
|
|
10292
10497
|
res.node = try p.addNode(.{ .int_literal = .{ .qt = res.qt, .literal_tok = tok_i } });
|
|
@@ -10604,12 +10809,7 @@ fn genericSelection(p: *Parser) Error!?Result {
|
|
|
10604
10809
|
}
|
|
10605
10810
|
|
|
10606
10811
|
test "Node locations" {
|
|
10607
|
-
var
|
|
10608
|
-
defer arena_state.deinit();
|
|
10609
|
-
const arena = arena_state.allocator();
|
|
10610
|
-
|
|
10611
|
-
var diagnostics: Diagnostics = .{ .output = .ignore };
|
|
10612
|
-
var comp = Compilation.init(std.testing.allocator, arena, std.testing.io, &diagnostics, Io.Dir.cwd());
|
|
10812
|
+
var comp = try Compilation.init(.testing);
|
|
10613
10813
|
defer comp.deinit();
|
|
10614
10814
|
|
|
10615
10815
|
const file = try comp.addSourceFromBuffer("file.c",
|
|
@@ -10621,7 +10821,7 @@ test "Node locations" {
|
|
|
10621
10821
|
|
|
10622
10822
|
const builtin_macros = try comp.generateBuiltinMacros(.no_system_defines);
|
|
10623
10823
|
|
|
10624
|
-
var pp = Preprocessor.init(&comp, .
|
|
10824
|
+
var pp = try Preprocessor.init(&comp, .testing);
|
|
10625
10825
|
defer pp.deinit();
|
|
10626
10826
|
try pp.addBuiltinMacros();
|
|
10627
10827
|
|
|
@@ -10633,7 +10833,6 @@ test "Node locations" {
|
|
|
10633
10833
|
var tree = try Parser.parse(&pp);
|
|
10634
10834
|
defer tree.deinit();
|
|
10635
10835
|
|
|
10636
|
-
try std.testing.expectEqual(0, comp.diagnostics.total);
|
|
10637
10836
|
for (tree.root_decls.items[tree.root_decls.items.len - 3 ..], 0..) |node, i| {
|
|
10638
10837
|
const slice = tree.tokSlice(node.tok(&tree));
|
|
10639
10838
|
const expected_slice = switch (i) {
|