authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-10-21 19:01:01+02:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-10-21 19:01:01+02:00
loged136f830665c38af3d0d4beb1177584cb6d40d7
tree8e5cefda3493dc7e6e1538f1e0e28683fb21b730
parente5e0b6ae5238cc78d335cc0a9cac7ba4250cb9ca
parentb2d0675f90cc4e26fdf7a81c1edda8f1b8a00f1f

Merge pull request 'compiler_rt: support targets where `c_longdouble` is not a valid type' (#37324) from jacobly/invalid-c-longdouble into master

Reviewed-on: https://codeberg.org/ziglang/zig/pulls/37324 Reviewed-by: Andrew Kelley <andrew@ziglang.org>

27 files changed, 122 insertions(+), 64 deletions(-)

lib/compiler_rt.zig+8
...@@ -399,6 +399,14 @@ fn complexAbi(comptime Float: type, comptime float: type) type {...@@ -399,6 +399,14 @@ fn complexAbi(comptime Float: type, comptime float: type) type {
399 };399 };
400}400}
401401
402pub const have_c_longdouble = if (builtin.target.cTypeBitSize(.longdouble)) |bits| switch (bits) {
403 else => true,
404 80 => switch (std.zig.target.compilerRtFloatAbi(&builtin.target, bits)) {
405 .soft => false,
406 .hard => true,
407 },
408} else false;
409
402pub fn Complex(comptime Float: type) type {410pub fn Complex(comptime Float: type) type {
403 return struct { real: Float, imag: Float };411 return struct { real: Float, imag: Float };
404}412}
lib/compiler_rt/cos.zig+4-2
...@@ -25,8 +25,10 @@ comptime {...@@ -25,8 +25,10 @@ comptime {
25 symbol(&cos, "cos");25 symbol(&cos, "cos");
26 symbol(&__cosx, "__cosx");26 symbol(&__cosx, "__cosx");
27 symbol(&cosq, "cosf128");27 symbol(&cosq, "cosf128");
28 symbol(&cosl, "cosl");28 if (compiler_rt.have_c_longdouble) {
29 symbol(&cosl, "__cosl"); // required by musl29 symbol(&cosl, "cosl");
30 symbol(&cosl, "__cosl"); // required by musl
31 }
30}32}
3133
32fn __cosh(x: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi {34fn __cosh(x: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi {
lib/compiler_rt/exp.zig+1-1
...@@ -22,7 +22,7 @@ comptime {...@@ -22,7 +22,7 @@ comptime {
22 symbol(&exp, "exp");22 symbol(&exp, "exp");
23 symbol(&__expx, "__expx");23 symbol(&__expx, "__expx");
24 symbol(&expq, "expf128");24 symbol(&expq, "expf128");
25 symbol(&expl, "expl");25 if (compiler_rt.have_c_longdouble) symbol(&expl, "expl");
26}26}
2727
28fn __exph(x: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi {28fn __exph(x: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi {
lib/compiler_rt/exp2.zig+1-1
...@@ -20,7 +20,7 @@ comptime {...@@ -20,7 +20,7 @@ comptime {
20 symbol(&exp2, "exp2");20 symbol(&exp2, "exp2");
21 symbol(&__exp2x, "__exp2x");21 symbol(&__exp2x, "__exp2x");
22 symbol(&exp2q, "exp2f128");22 symbol(&exp2q, "exp2f128");
23 symbol(&exp2l, "exp2l");23 if (compiler_rt.have_c_longdouble) symbol(&exp2l, "exp2l");
24}24}
2525
26fn __exp2h(x: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi {26fn __exp2h(x: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi {
lib/compiler_rt/fabs.zig+1-1
...@@ -10,7 +10,7 @@ comptime {...@@ -10,7 +10,7 @@ comptime {
10 symbol(&fabs, "fabs");10 symbol(&fabs, "fabs");
11 symbol(&__fabsx, "__fabsx");11 symbol(&__fabsx, "__fabsx");
12 symbol(&fabsq, "fabsf128");12 symbol(&fabsq, "fabsf128");
13 symbol(&fabsl, "fabsl");13 if (compiler_rt.have_c_longdouble) symbol(&fabsl, "fabsl");
14}14}
1515
16fn __fabsh(a: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi {16fn __fabsh(a: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi {
lib/compiler_rt/floor_ceil.zig+2-2
...@@ -24,7 +24,7 @@ comptime {...@@ -24,7 +24,7 @@ comptime {
24 symbol(&floor, "floor");24 symbol(&floor, "floor");
25 symbol(&__floorx, "__floorx");25 symbol(&__floorx, "__floorx");
26 symbol(&floorq, "floorf128");26 symbol(&floorq, "floorf128");
27 symbol(&floorl, "floorl");27 if (compiler_rt.have_c_longdouble) symbol(&floorl, "floorl");
2828
29 // ceil29 // ceil
30 symbol(&__ceilh, "__ceilh");30 symbol(&__ceilh, "__ceilh");
...@@ -32,7 +32,7 @@ comptime {...@@ -32,7 +32,7 @@ comptime {
32 symbol(&ceil, "ceil");32 symbol(&ceil, "ceil");
33 symbol(&__ceilx, "__ceilx");33 symbol(&__ceilx, "__ceilx");
34 symbol(&ceilq, "ceilf128");34 symbol(&ceilq, "ceilf128");
35 symbol(&ceill, "ceill");35 if (compiler_rt.have_c_longdouble) symbol(&ceill, "ceill");
36}36}
3737
38fn __floorh(x: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi {38fn __floorh(x: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi {
lib/compiler_rt/fma.zig+1-1
...@@ -18,7 +18,7 @@ comptime {...@@ -18,7 +18,7 @@ comptime {
18 symbol(&fma, "fma");18 symbol(&fma, "fma");
19 symbol(&__fmax, "__fmax");19 symbol(&__fmax, "__fmax");
20 symbol(&fmaq, "fmaf128");20 symbol(&fmaq, "fmaf128");
21 symbol(&fmal, "fmal");21 if (compiler_rt.have_c_longdouble) symbol(&fmal, "fmal");
22}22}
2323
24fn __fmah(x: compiler_rt.f16.Abi, y: compiler_rt.f16.Abi, z: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi {24fn __fmah(x: compiler_rt.f16.Abi, y: compiler_rt.f16.Abi, z: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi {
lib/compiler_rt/fmax.zig+1-1
...@@ -11,7 +11,7 @@ comptime {...@@ -11,7 +11,7 @@ comptime {
11 symbol(&fmax, "fmax");11 symbol(&fmax, "fmax");
12 symbol(&__fmaxx, "__fmaxx");12 symbol(&__fmaxx, "__fmaxx");
13 symbol(&fmaxq, "fmaxf128");13 symbol(&fmaxq, "fmaxf128");
14 symbol(&fmaxl, "fmaxl");14 if (compiler_rt.have_c_longdouble) symbol(&fmaxl, "fmaxl");
15}15}
1616
17fn __fmaxh(x: compiler_rt.f16.Abi, y: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi {17fn __fmaxh(x: compiler_rt.f16.Abi, y: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi {
lib/compiler_rt/fmin.zig+1-1
...@@ -11,7 +11,7 @@ comptime {...@@ -11,7 +11,7 @@ comptime {
11 symbol(&fmin, "fmin");11 symbol(&fmin, "fmin");
12 symbol(&__fminx, "__fminx");12 symbol(&__fminx, "__fminx");
13 symbol(&fminq, "fminf128");13 symbol(&fminq, "fminf128");
14 symbol(&fminl, "fminl");14 if (compiler_rt.have_c_longdouble) symbol(&fminl, "fminl");
15}15}
1616
17fn __fminh(x: compiler_rt.f16.Abi, y: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi {17fn __fminh(x: compiler_rt.f16.Abi, y: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi {
lib/compiler_rt/fmod.zig+1-1
...@@ -13,7 +13,7 @@ comptime {...@@ -13,7 +13,7 @@ comptime {
13 symbol(&fmod, "fmod");13 symbol(&fmod, "fmod");
14 symbol(&__fmodx, "__fmodx");14 symbol(&__fmodx, "__fmodx");
15 symbol(&fmodq, "fmodf128");15 symbol(&fmodq, "fmodf128");
16 symbol(&fmodl, "fmodl");16 if (compiler_rt.have_c_longdouble) symbol(&fmodl, "fmodl");
17}17}
1818
19fn __fmodh(a: compiler_rt.f16.Abi, b: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi {19fn __fmodh(a: compiler_rt.f16.Abi, b: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi {
lib/compiler_rt/log.zig+1-1
...@@ -19,7 +19,7 @@ comptime {...@@ -19,7 +19,7 @@ comptime {
19 symbol(&log, "log");19 symbol(&log, "log");
20 symbol(&__logx, "__logx");20 symbol(&__logx, "__logx");
21 symbol(&logq, "logf128");21 symbol(&logq, "logf128");
22 symbol(&logl, "logl");22 if (compiler_rt.have_c_longdouble) symbol(&logl, "logl");
23}23}
2424
25fn __logh(a: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi {25fn __logh(a: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi {
lib/compiler_rt/log10.zig+1-1
...@@ -19,7 +19,7 @@ comptime {...@@ -19,7 +19,7 @@ comptime {
19 symbol(&log10, "log10");19 symbol(&log10, "log10");
20 symbol(&__log10x, "__log10x");20 symbol(&__log10x, "__log10x");
21 symbol(&log10q, "log10f128");21 symbol(&log10q, "log10f128");
22 symbol(&log10l, "log10l");22 if (compiler_rt.have_c_longdouble) symbol(&log10l, "log10l");
23}23}
2424
25fn __log10h(a: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi {25fn __log10h(a: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi {
lib/compiler_rt/log2.zig+1-1
...@@ -20,7 +20,7 @@ comptime {...@@ -20,7 +20,7 @@ comptime {
20 symbol(&log2, "log2");20 symbol(&log2, "log2");
21 symbol(&__log2x, "__log2x");21 symbol(&__log2x, "__log2x");
22 symbol(&log2q, "log2f128");22 symbol(&log2q, "log2f128");
23 symbol(&log2l, "log2l");23 if (compiler_rt.have_c_longdouble) symbol(&log2l, "log2l");
24}24}
2525
26fn __log2h(a: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi {26fn __log2h(a: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi {
lib/compiler_rt/round.zig+1-1
...@@ -19,7 +19,7 @@ comptime {...@@ -19,7 +19,7 @@ comptime {
19 symbol(&round, "round");19 symbol(&round, "round");
20 symbol(&__roundx, "__roundx");20 symbol(&__roundx, "__roundx");
21 symbol(&roundq, "roundf128");21 symbol(&roundq, "roundf128");
22 symbol(&roundl, "roundl");22 if (compiler_rt.have_c_longdouble) symbol(&roundl, "roundl");
23}23}
2424
25fn __roundh(x: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi {25fn __roundh(x: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi {
lib/compiler_rt/sin.zig+4-2
...@@ -25,8 +25,10 @@ comptime {...@@ -25,8 +25,10 @@ comptime {
25 symbol(&sin, "sin");25 symbol(&sin, "sin");
26 symbol(&__sinx, "__sinx");26 symbol(&__sinx, "__sinx");
27 symbol(&sinq, "sinf128");27 symbol(&sinq, "sinf128");
28 symbol(&sinl, "sinl");28 if (compiler_rt.have_c_longdouble) {
29 symbol(&sinl, "__sinl"); // required by musl29 symbol(&sinl, "sinl");
30 symbol(&sinl, "__sinl"); // required by musl
31 }
30}32}
3133
32fn __sinh(x: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi {34fn __sinh(x: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi {
lib/compiler_rt/sincos.zig+1-1
...@@ -19,7 +19,7 @@ comptime {...@@ -19,7 +19,7 @@ comptime {
19 symbol(&sincos, "sincos");19 symbol(&sincos, "sincos");
20 symbol(&sincosx, "__sincosx");20 symbol(&sincosx, "__sincosx");
21 symbol(&sincosq, "sincosf128");21 symbol(&sincosq, "sincosf128");
22 symbol(&sincosl, "sincosl");22 if (compiler_rt.have_c_longdouble) symbol(&sincosl, "sincosl");
23}23}
2424
25fn sincosh(x: compiler_rt.f16.Abi, r_sin: *compiler_rt.f16.Abi, r_cos: *compiler_rt.f16.Abi) callconv(.c) void {25fn sincosh(x: compiler_rt.f16.Abi, r_sin: *compiler_rt.f16.Abi, r_cos: *compiler_rt.f16.Abi) callconv(.c) void {
lib/compiler_rt/sqrt.zig+1-1
...@@ -23,7 +23,7 @@ comptime {...@@ -23,7 +23,7 @@ comptime {
23 } else if (compiler_rt.want_sparc32_abi) {23 } else if (compiler_rt.want_sparc32_abi) {
24 symbol(&sqrtq, "_Q_sqrt");24 symbol(&sqrtq, "_Q_sqrt");
25 }25 }
26 symbol(&sqrtl, "sqrtl");26 if (compiler_rt.have_c_longdouble) symbol(&sqrtl, "sqrtl");
27}27}
2828
29fn __sqrth(x: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi {29fn __sqrth(x: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi {
lib/compiler_rt/tan.zig+1-1
...@@ -29,7 +29,7 @@ comptime {...@@ -29,7 +29,7 @@ comptime {
29 symbol(&tan, "tan");29 symbol(&tan, "tan");
30 symbol(&__tanx, "__tanx");30 symbol(&__tanx, "__tanx");
31 symbol(&tanq, "tanf128");31 symbol(&tanq, "tanf128");
32 symbol(&tanl, "tanl");32 if (compiler_rt.have_c_longdouble) symbol(&tanl, "tanl");
33}33}
3434
35fn __tanh(x: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi {35fn __tanh(x: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi {
lib/compiler_rt/trunc.zig+1-1
...@@ -18,7 +18,7 @@ comptime {...@@ -18,7 +18,7 @@ comptime {
18 symbol(&trunc, "trunc");18 symbol(&trunc, "trunc");
19 symbol(&__truncx, "__truncx");19 symbol(&__truncx, "__truncx");
20 symbol(&truncq, "truncf128");20 symbol(&truncq, "truncf128");
21 symbol(&truncl, "truncl");21 if (compiler_rt.have_c_longdouble) symbol(&truncl, "truncl");
22}22}
2323
24fn __trunch(x: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi {24fn __trunch(x: compiler_rt.f16.Abi) callconv(.c) compiler_rt.f16.Abi {
lib/std/Target.zig+9-9
...@@ -3212,7 +3212,7 @@ pub const CType = enum {...@@ -3212,7 +3212,7 @@ pub const CType = enum {
3212 longdouble,3212 longdouble,
3213};3213};
32143214
3215/// Returns `null` if no C ABI is defined for this target.3215/// Returns `null` if no C ABI for `c_type` is defined for this target.
3216pub fn cTypeByteSize(t: *const Target, c_type: CType) ?u16 {3216pub fn cTypeByteSize(t: *const Target, c_type: CType) ?u16 {
3217 return switch (c_type) {3217 return switch (c_type) {
3218 .char,3218 .char,
...@@ -3238,7 +3238,7 @@ pub fn cTypeByteSize(t: *const Target, c_type: CType) ?u16 {...@@ -3238,7 +3238,7 @@ pub fn cTypeByteSize(t: *const Target, c_type: CType) ?u16 {
3238 };3238 };
3239}3239}
32403240
3241/// Returns `null` if no C ABI is defined for this target.3241/// Returns `null` if no C ABI for `c_type` is defined for this target.
3242pub fn cTypeBitSize(target: *const Target, c_type: CType) ?u16 {3242pub fn cTypeBitSize(target: *const Target, c_type: CType) ?u16 {
3243 return switch (target.os.tag) {3243 return switch (target.os.tag) {
3244 .freestanding,3244 .freestanding,
...@@ -3285,7 +3285,7 @@ pub fn cTypeBitSize(target: *const Target, c_type: CType) ?u16 {...@@ -3285,7 +3285,7 @@ pub fn cTypeBitSize(target: *const Target, c_type: CType) ?u16 {
32853285
3286 .x86,3286 .x86,
3287 .x86_64,3287 .x86_64,
3288 => 80,3288 => if (target.cpu.has(.x86, .x87)) 80 else null,
32893289
3290 .alpha,3290 .alpha,
3291 .riscv32,3291 .riscv32,
...@@ -3345,7 +3345,7 @@ pub fn cTypeBitSize(target: *const Target, c_type: CType) ?u16 {...@@ -3345,7 +3345,7 @@ pub fn cTypeBitSize(target: *const Target, c_type: CType) ?u16 {
3345 .x86_64,3345 .x86_64,
3346 => switch (target.abi) {3346 => switch (target.abi) {
3347 .android, .ohos => 64,3347 .android, .ohos => 64,
3348 else => 80,3348 else => if (target.cpu.has(.x86, .x87)) 80 else null,
3349 },3349 },
33503350
3351 .powerpc,3351 .powerpc,
...@@ -3409,7 +3409,7 @@ pub fn cTypeBitSize(target: *const Target, c_type: CType) ?u16 {...@@ -3409,7 +3409,7 @@ pub fn cTypeBitSize(target: *const Target, c_type: CType) ?u16 {
3409 .long, .ulong => 32,3409 .long, .ulong => 32,
3410 .longlong, .ulonglong, .double => 64,3410 .longlong, .ulonglong, .double => 64,
3411 .longdouble => switch (target.abi) {3411 .longdouble => switch (target.abi) {
3412 .gnu => 80,3412 .gnu => if (target.cpu.has(.x86, .x87)) 80 else null,
3413 else => 64,3413 else => 64,
3414 },3414 },
3415 },3415 },
...@@ -3420,7 +3420,7 @@ pub fn cTypeBitSize(target: *const Target, c_type: CType) ?u16 {...@@ -3420,7 +3420,7 @@ pub fn cTypeBitSize(target: *const Target, c_type: CType) ?u16 {
3420 .long, .ulong => 32,3420 .long, .ulong => 32,
3421 .longlong, .ulonglong, .double => 64,3421 .longlong, .ulonglong, .double => 64,
3422 .longdouble => switch (target.abi) {3422 .longdouble => switch (target.abi) {
3423 .gnu => 80,3423 .gnu => if (target.cpu.has(.x86, .x87)) 80 else null,
3424 else => 64,3424 else => 64,
3425 },3425 },
3426 },3426 },
...@@ -3454,7 +3454,7 @@ pub fn cTypeBitSize(target: *const Target, c_type: CType) ?u16 {...@@ -3454,7 +3454,7 @@ pub fn cTypeBitSize(target: *const Target, c_type: CType) ?u16 {
3454 },3454 },
3455 .longlong, .ulonglong, .double => 64,3455 .longlong, .ulonglong, .double => 64,
3456 .longdouble => switch (target.cpu.arch) {3456 .longdouble => switch (target.cpu.arch) {
3457 .x86_64 => 80,3457 .x86_64 => if (target.cpu.has(.x86, .x87)) 80 else null,
3458 else => 64,3458 else => 64,
3459 },3459 },
3460 },3460 },
...@@ -3492,14 +3492,14 @@ pub fn cTypeBitSize(target: *const Target, c_type: CType) ?u16 {...@@ -3492,14 +3492,14 @@ pub fn cTypeBitSize(target: *const Target, c_type: CType) ?u16 {
3492 .short, .ushort => 16,3492 .short, .ushort => 16,
3493 .int, .uint, .float => 32,3493 .int, .uint, .float => 32,
3494 .long, .ulong, .longlong, .ulonglong, .double => 64,3494 .long, .ulong, .longlong, .ulonglong, .double => 64,
3495 .longdouble => 80,3495 .longdouble => if (target.cpu.has(.x86, .x87)) 80 else null,
3496 },3496 },
34973497
3498 .opengl => null,3498 .opengl => null,
3499 };3499 };
3500}3500}
35013501
3502/// Returns `null` if no C ABI is defined for this target.3502/// Returns `null` if no C ABI for `c_type` is defined for this target.
3503pub fn cTypeAlignment(target: *const Target, c_type: CType) ?u16 {3503pub fn cTypeAlignment(target: *const Target, c_type: CType) ?u16 {
3504 // Overrides for unusual alignments3504 // Overrides for unusual alignments
3505 switch (target.cpu.arch) {3505 switch (target.cpu.arch) {
lib/std/math/float.zig+5-4
...@@ -12,10 +12,11 @@ pub const long_double = struct {...@@ -12,10 +12,11 @@ pub const long_double = struct {
1212
13 inline fn bitWidth(x: anytype) u16 {13 inline fn bitWidth(x: anytype) u16 {
14 const T = @TypeOf(x);14 const T = @TypeOf(x);
15 return switch (T) {15 switch (@typeInfo(T)) {
16 f80, f128, c_longdouble => @typeInfo(T).float.bits,16 .float => |float| if (float.bits >= 80) return float.bits,
17 else => @compileError("Unsupported type: " ++ @typeName(T) ++ "\nPass a `f80`, `f128`, or `c_longdouble`."),17 else => {},
18 };18 }
19 @compileError("Unsupported type: " ++ @typeName(T) ++ "\nPass a `f80`, `f128`, or `c_longdouble`.");
19 }20 }
2021
21 /// Returns the sign + exponent bits of a `long double`.22 /// Returns the sign + exponent bits of a `long double`.
lib/std/zig/AstGen.zig+16
...@@ -8140,6 +8140,22 @@ fn identifier(...@@ -8140,6 +8140,22 @@ fn identifier(
8140 // if not @"" syntax, just use raw token slice8140 // if not @"" syntax, just use raw token slice
8141 if (ident_name_raw[0] != '@') {8141 if (ident_name_raw[0] != '@') {
8142 if (primitive_instrs.get(ident_name_raw)) |zir_const_ref| {8142 if (primitive_instrs.get(ident_name_raw)) |zir_const_ref| {
8143 const maybe_c_type: ?std.Target.CType = switch (zir_const_ref) {
8144 else => null,
8145 .c_char_type => .char,
8146 .c_short_type => .short,
8147 .c_ushort_type => .ushort,
8148 .c_int_type => .int,
8149 .c_uint_type => .uint,
8150 .c_long_type => .long,
8151 .c_ulong_type => .ulong,
8152 .c_longlong_type => .longlong,
8153 .c_ulonglong_type => .ulonglong,
8154 .c_longdouble_type => .longdouble,
8155 };
8156 if (maybe_c_type) |c_type| {
8157 _ = try gz.addExtendedNodeSmall(.validate_c_type, ident, @backingInt(c_type));
8158 }
8143 return rvalue(gz, ri, zir_const_ref, ident);8159 return rvalue(gz, ri, zir_const_ref, ident);
8144 }8160 }
81458161
lib/std/zig/Zir.zig+6
...@@ -2186,6 +2186,11 @@ pub const Inst = struct {...@@ -2186,6 +2186,11 @@ pub const Inst = struct {
2186 /// For example: Provided with `error{Foo}!?f64`, returns `f64`.2186 /// For example: Provided with `error{Foo}!?f64`, returns `f64`.
2187 /// `operand` is payload index to `UnNode`.2187 /// `operand` is payload index to `UnNode`.
2188 float_op_result_ty,2188 float_op_result_ty,
2189 /// Validate that the given `CType` is valid for the current target.
2190 /// This can be folded into the `@CType` tag once that is implemented.
2191 /// `operand` is `src_node: Ast.Node.Offset`.
2192 /// `small` is a `std.Target.CType`.
2193 validate_c_type,
21892194
2190 pub const InstData = struct {2195 pub const InstData = struct {
2191 opcode: Extended,2196 opcode: Extended,
...@@ -4441,6 +4446,7 @@ fn findTrackableInner(...@@ -4441,6 +4446,7 @@ fn findTrackableInner(
4441 .astgen_error,4446 .astgen_error,
4442 .float_op_result_ty,4447 .float_op_result_ty,
4443 .round_op_ty,4448 .round_op_ty,
4449 .validate_c_type,
4444 => return,4450 => return,
44454451
4446 // `@TypeOf` has a body.4452 // `@TypeOf` has a body.
src/Compilation.zig+28-27
...@@ -6761,39 +6761,40 @@ pub fn addCCArgs(...@@ -6761,39 +6761,40 @@ pub fn addCCArgs(
6761 else => &.{"-Xclang"},6761 else => &.{"-Xclang"},
6762 };6762 };
67636763
6764 for (xclang_flags) |xclang| {6764 if (target_util.clangSupportsTargetCpuArg(target)) {
6765 if (target_util.clangSupportsTargetCpuArg(target)) {6765 if (target.cpu.model.llvm_name) |llvm_name| {
6766 if (target.cpu.model.llvm_name) |llvm_name| {6766 for (xclang_flags) |xclang| {
6767 try argv.appendSlice(&[_][]const u8{6767 try argv.appendSlice(&[_][]const u8{
6768 xclang, "-target-cpu", xclang, llvm_name,6768 xclang, "-target-cpu", xclang, llvm_name,
6769 });6769 });
6770 }6770 }
6771 }6771 }
6772 }
6773
6774 // It would be really nice if there was a more compact way to communicate this info to Clang.
6775 const all_features_list = target.cpu.arch.allFeaturesList();
6776 try argv.ensureUnusedCapacity(all_features_list.len * xclang_flags.len * 4);
6777 for (all_features_list, 0..) |feature, index_usize| {
6778 const index = @as(std.Target.Cpu.Feature.Set.Index, @intCast(index_usize));
6779 const is_enabled = target.cpu.features.isEnabled(index);
67726780
6773 // It would be really nice if there was a more compact way to communicate this info to Clang.6781 if (feature.llvm_name) |llvm_name| {
6774 const all_features_list = target.cpu.arch.allFeaturesList();6782 // We communicate these to Clang through the dedicated options.
6775 try argv.ensureUnusedCapacity(all_features_list.len * 4);6783 if (std.mem.startsWith(u8, llvm_name, "soft-float") or
6776 for (all_features_list, 0..) |feature, index_usize| {6784 std.mem.startsWith(u8, llvm_name, "hard-float") or
6777 const index = @as(std.Target.Cpu.Feature.Set.Index, @intCast(index_usize));6785 (target.cpu.arch.isPowerPC() and std.mem.startsWith(u8, llvm_name, "64bit")) or
6778 const is_enabled = target.cpu.features.isEnabled(index);6786 (target.cpu.arch.isX86() and std.mem.startsWith(u8, llvm_name, "x32")) or
67796787 (target.cpu.arch == .s390x and std.mem.eql(u8, llvm_name, "backchain")))
6780 if (feature.llvm_name) |llvm_name| {6788 continue;
6781 // We communicate these to Clang through the dedicated options.6789
6782 if (std.mem.startsWith(u8, llvm_name, "soft-float") or6790 // Ignore these until we figure out how to handle the concept of omitting features.
6783 std.mem.startsWith(u8, llvm_name, "hard-float") or6791 // See https://github.com/ziglang/zig/issues/23539
6784 (target.cpu.arch.isPowerPC() and std.mem.startsWith(u8, llvm_name, "64bit")) or6792 if (target_util.isDynamicAMDGCNFeature(target, feature)) continue;
6785 (target.cpu.arch.isX86() and std.mem.startsWith(u8, llvm_name, "x32")) or6793
6786 (target.cpu.arch == .s390x and std.mem.eql(u8, llvm_name, "backchain")))6794 const plus_or_minus = "-+"[@intFromBool(is_enabled)];
6787 continue;6795 const arg = try std.fmt.allocPrint(arena, "{c}{s}", .{ plus_or_minus, llvm_name });
67886796 for (xclang_flags) |xclang| {
6789 // Ignore these until we figure out how to handle the concept of omitting features.6797 argv.appendSliceAssumeCapacity(&[_][]const u8{ xclang, "-target-feature", xclang, arg });
6790 // See https://github.com/ziglang/zig/issues/23539
6791 if (target_util.isDynamicAMDGCNFeature(target, feature)) continue;
6792
6793 argv.appendSliceAssumeCapacity(&[_][]const u8{ xclang, "-target-feature", xclang });
6794 const plus_or_minus = "-+"[@intFromBool(is_enabled)];
6795 const arg = try std.fmt.allocPrint(arena, "{c}{s}", .{ plus_or_minus, llvm_name });
6796 argv.appendAssumeCapacity(arg);
6797 }6798 }
6798 }6799 }
6799 }6800 }
src/Sema.zig+13
...@@ -1469,6 +1469,11 @@ fn analyzeBodyInner(...@@ -1469,6 +1469,11 @@ fn analyzeBodyInner(
1469 },1469 },
1470 .astgen_error => return sema.failTransitive(.astgen_error),1470 .astgen_error => return sema.failTransitive(.astgen_error),
1471 .float_op_result_ty => try sema.zirFloatOpResultType(block, extended),1471 .float_op_result_ty => try sema.zirFloatOpResultType(block, extended),
1472 .validate_c_type => {
1473 try sema.zirValidateCType(block, extended);
1474 i += 1;
1475 continue;
1476 },
1472 };1477 };
1473 },1478 },
14741479
...@@ -4315,6 +4320,14 @@ fn zirTryOperandTy(sema: *Sema, block: *Block, inst: Zir.Inst.Index, is_ref: boo...@@ -4315,6 +4320,14 @@ fn zirTryOperandTy(sema: *Sema, block: *Block, inst: Zir.Inst.Index, is_ref: boo
4315 }4320 }
4316}4321}
43174322
4323fn zirValidateCType(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!void {
4324 const c_type: std.Target.CType = @fromBackingInt(@intCast(extended.small));
4325 if (sema.pt.zcu.getTarget().cTypeBitSize(c_type)) |_| return;
4326 const src_node: std.zig.Ast.Node.Offset = @fromBackingInt(@bitCast(extended.operand));
4327 const src = block.nodeOffset(src_node);
4328 return sema.fail(block, src, "'c_{t}' is not valid on this target", .{c_type});
4329}
4330
4318fn zirValidateRefTy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {4331fn zirValidateRefTy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {
4319 const pt = sema.pt;4332 const pt = sema.pt;
4320 const zcu = pt.zcu;4333 const zcu = pt.zcu;
src/Type.zig+4-1
...@@ -3178,7 +3178,10 @@ pub fn validateExtern(ty: Type, position: ExternPosition, zcu: *const Zcu) bool...@@ -3178,7 +3178,10 @@ pub fn validateExtern(ty: Type, position: ExternPosition, zcu: *const Zcu) bool
3178 },3178 },
3179 .float => switch (ty.floatBits(zcu.getTarget())) {3179 .float => switch (ty.floatBits(zcu.getTarget())) {
3180 else => true,3180 else => true,
3181 80 => |bits| std.zig.target.compilerRtFloatAbi(zcu.getTarget(), bits) == .hard,3181 80 => |bits| switch (std.zig.target.compilerRtFloatAbi(zcu.getTarget(), bits)) {
3182 .soft => false,
3183 .hard => true,
3184 },
3182 },3185 },
3183 .@"fn" => {3186 .@"fn" => {
3184 if (position != .other) return false;3187 if (position != .other) return false;
src/print_zir.zig+8-2
...@@ -712,8 +712,14 @@ const Writer = struct {...@@ -712,8 +712,14 @@ const Writer = struct {
712 .std_lang_value => try self.writeStdLangValue(stream, extended),712 .std_lang_value => try self.writeStdLangValue(stream, extended),
713 .inplace_arith_result_ty => try self.writeInplaceArithResultTy(stream, extended),713 .inplace_arith_result_ty => try self.writeInplaceArithResultTy(stream, extended),
714714
715 .dbg_empty_stmt => try stream.writeAll("))"),715 .dbg_empty_stmt, .astgen_error => try stream.writeAll("))"),
716 .astgen_error => try stream.writeAll("))"),716
717 .validate_c_type => {
718 const c_type: std.Target.CType = @fromBackingInt(@intCast(extended.small));
719 const src_node: Ast.Node.Offset = @fromBackingInt(@bitCast(extended.operand));
720 try stream.print("{t})) ", .{c_type});
721 try self.writeSrcNode(stream, src_node);
722 },
717 }723 }
718 }724 }
719725