aboutsummaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2021-03-28 21:42:56 -0700
committerAndrew Kelley <andrew@ziglang.org>2021-03-28 21:42:56 -0700
commitb85ef2300fa72f5f4c73b8eb9e14f0218ada592d (patch)
treedaee8ab81eaefb5433f6ba3750656ba769a311a4 /test
parent75080e351af8be45722bca50c1d5fcd503304d77 (diff)
parent175adc0bd738c2e3a55bb71c6a53dcc920c203ba (diff)
downloadzig-b85ef2300fa72f5f4c73b8eb9e14f0218ada592d.tar.gz
zig-b85ef2300fa72f5f4c73b8eb9e14f0218ada592d.zip
Merge remote-tracking branch 'origin/master' into llvm12
Diffstat (limited to 'test')
-rw-r--r--test/cli.zig11
-rw-r--r--test/run_translated_c.zig121
-rw-r--r--test/stage1/behavior/vector.zig12
-rw-r--r--test/stage2/cbe.zig2
-rw-r--r--test/stage2/wasm.zig35
-rw-r--r--test/standalone.zig5
-rw-r--r--test/standalone/mix_o_files/base64.zig6
-rw-r--r--test/translate_c.zig202
8 files changed, 309 insertions, 85 deletions
diff --git a/test/cli.zig b/test/cli.zig
index c0702fa54c..dedea67a59 100644
--- a/test/cli.zig
+++ b/test/cli.zig
@@ -28,6 +28,8 @@ pub fn main() !void {
const zig_exe = try fs.path.resolve(a, &[_][]const u8{zig_exe_rel});
const dir_path = try fs.path.join(a, &[_][]const u8{ cache_root, "clitest" });
+ defer fs.cwd().deleteTree(dir_path) catch {};
+
const TestFn = fn ([]const u8, []const u8) anyerror!void;
const test_fns = [_]TestFn{
testZigInitLib,
@@ -174,4 +176,13 @@ fn testZigFmt(zig_exe: []const u8, dir_path: []const u8) !void {
const run_result3 = try exec(dir_path, true, &[_][]const u8{ zig_exe, "fmt", dir_path });
// both files have been formatted, nothing should change now
testing.expect(run_result3.stdout.len == 0);
+
+ // Check UTF-16 decoding
+ const fmt4_zig_path = try fs.path.join(a, &[_][]const u8{ dir_path, "fmt4.zig" });
+ var unformatted_code_utf16 = "\xff\xfe \x00 \x00 \x00 \x00/\x00/\x00 \x00n\x00o\x00 \x00r\x00e\x00a\x00s\x00o\x00n\x00";
+ try fs.cwd().writeFile(fmt4_zig_path, unformatted_code_utf16);
+
+ const run_result4 = try exec(dir_path, true, &[_][]const u8{ zig_exe, "fmt", dir_path });
+ testing.expect(std.mem.startsWith(u8, run_result4.stdout, fmt4_zig_path));
+ testing.expect(run_result4.stdout.len == fmt4_zig_path.len + 1 and run_result4.stdout[run_result4.stdout.len - 1] == '\n');
}
diff --git a/test/run_translated_c.zig b/test/run_translated_c.zig
index 01df88c852..6cac9cd79d 100644
--- a/test/run_translated_c.zig
+++ b/test/run_translated_c.zig
@@ -3,6 +3,17 @@ const tests = @import("tests.zig");
const nl = std.cstr.line_sep;
pub fn addCases(cases: *tests.RunTranslatedCContext) void {
+ cases.add("division of floating literals",
+ \\#define _NO_CRT_STDIO_INLINE 1
+ \\#include <stdio.h>
+ \\#define PI 3.14159265358979323846f
+ \\#define DEG2RAD (PI/180.0f)
+ \\int main(void) {
+ \\ printf("DEG2RAD is: %f\n", DEG2RAD);
+ \\ return 0;
+ \\}
+ , "DEG2RAD is: 0.017453" ++ nl);
+
cases.add("use global scope for record/enum/typedef type transalation if needed",
\\void bar(void);
\\void baz(void);
@@ -1187,4 +1198,114 @@ pub fn addCases(cases: *tests.RunTranslatedCContext) void {
\\ return 0;
\\}
, "");
+
+ cases.add("Generic selections",
+ \\#include <stdlib.h>
+ \\#include <string.h>
+ \\#include <stdint.h>
+ \\#define my_generic_fn(X) _Generic((X), \
+ \\ int: abs, \
+ \\ char *: strlen, \
+ \\ size_t: malloc, \
+ \\ default: free \
+ \\)(X)
+ \\#define my_generic_val(X) _Generic((X), \
+ \\ int: 1, \
+ \\ const char *: "bar" \
+ \\)
+ \\int main(void) {
+ \\ if (my_generic_val(100) != 1) abort();
+ \\
+ \\ const char *foo = "foo";
+ \\ const char *bar = my_generic_val(foo);
+ \\ if (strcmp(bar, "bar") != 0) abort();
+ \\
+ \\ if (my_generic_fn(-42) != 42) abort();
+ \\ if (my_generic_fn("hello") != 5) abort();
+ \\
+ \\ size_t size = 8192;
+ \\ uint8_t *mem = my_generic_fn(size);
+ \\ memset(mem, 42, size);
+ \\ if (mem[size - 1] != 42) abort();
+ \\ my_generic_fn(mem);
+ \\
+ \\ return 0;
+ \\}
+ , "");
+
+ // See __builtin_alloca_with_align comment in std.c.builtins
+ cases.add("use of unimplemented builtin in unused function does not prevent compilation",
+ \\#include <stdlib.h>
+ \\void unused() {
+ \\ __builtin_alloca_with_align(1, 8);
+ \\}
+ \\int main(void) {
+ \\ if (__builtin_sqrt(1.0) != 1.0) abort();
+ \\ return 0;
+ \\}
+ , "");
+
+ cases.add("convert single-statement bodies into blocks for if/else/for/while. issue #8159",
+ \\#include <stdlib.h>
+ \\int foo() { return 1; }
+ \\int main(void) {
+ \\ int i = 0;
+ \\ if (i == 0) if (i == 0) if (i != 0) i = 1;
+ \\ if (i != 0) i = 1; else if (i == 0) if (i == 0) i += 1;
+ \\ for (; i < 10;) for (; i < 10;) i++;
+ \\ while (i == 100) while (i == 100) foo();
+ \\ if (0) do do "string"; while(1); while(1);
+ \\ return 0;
+ \\}
+ , "");
+
+ cases.add("cast RHS of compound assignment if necessary, unused result",
+ \\#include <stdlib.h>
+ \\int main(void) {
+ \\ signed short val = -1;
+ \\ val += 1; if (val != 0) abort();
+ \\ val -= 1; if (val != -1) abort();
+ \\ val *= 2; if (val != -2) abort();
+ \\ val /= 2; if (val != -1) abort();
+ \\ val %= 2; if (val != -1) abort();
+ \\ val <<= 1; if (val != -2) abort();
+ \\ val >>= 1; if (val != -1) abort();
+ \\ val += 100000000; // compile error if @truncate() not inserted
+ \\ unsigned short uval = 1;
+ \\ uval += 1; if (uval != 2) abort();
+ \\ uval -= 1; if (uval != 1) abort();
+ \\ uval *= 2; if (uval != 2) abort();
+ \\ uval /= 2; if (uval != 1) abort();
+ \\ uval %= 2; if (uval != 1) abort();
+ \\ uval <<= 1; if (uval != 2) abort();
+ \\ uval >>= 1; if (uval != 1) abort();
+ \\ uval += 100000000; // compile error if @truncate() not inserted
+ \\}
+ , "");
+
+ cases.add("cast RHS of compound assignment if necessary, used result",
+ \\#include <stdlib.h>
+ \\int main(void) {
+ \\ signed short foo;
+ \\ signed short val = -1;
+ \\ foo = (val += 1); if (foo != 0) abort();
+ \\ foo = (val -= 1); if (foo != -1) abort();
+ \\ foo = (val *= 2); if (foo != -2) abort();
+ \\ foo = (val /= 2); if (foo != -1) abort();
+ \\ foo = (val %= 2); if (foo != -1) abort();
+ \\ foo = (val <<= 1); if (foo != -2) abort();
+ \\ foo = (val >>= 1); if (foo != -1) abort();
+ \\ foo = (val += 100000000); // compile error if @truncate() not inserted
+ \\ unsigned short ufoo;
+ \\ unsigned short uval = 1;
+ \\ ufoo = (uval += 1); if (ufoo != 2) abort();
+ \\ ufoo = (uval -= 1); if (ufoo != 1) abort();
+ \\ ufoo = (uval *= 2); if (ufoo != 2) abort();
+ \\ ufoo = (uval /= 2); if (ufoo != 1) abort();
+ \\ ufoo = (uval %= 2); if (ufoo != 1) abort();
+ \\ ufoo = (uval <<= 1); if (ufoo != 2) abort();
+ \\ ufoo = (uval >>= 1); if (ufoo != 1) abort();
+ \\ ufoo = (uval += 100000000); // compile error if @truncate() not inserted
+ \\}
+ , "");
}
diff --git a/test/stage1/behavior/vector.zig b/test/stage1/behavior/vector.zig
index eb505a9ae4..d3276496de 100644
--- a/test/stage1/behavior/vector.zig
+++ b/test/stage1/behavior/vector.zig
@@ -4,7 +4,7 @@ const mem = std.mem;
const math = std.math;
const expect = std.testing.expect;
const expectEqual = std.testing.expectEqual;
-const expectWithinEpsilon = std.testing.expectWithinEpsilon;
+const expectApproxEqRel = std.testing.expectApproxEqRel;
const Vector = std.meta.Vector;
test "implicit cast vector to array - bool" {
@@ -527,10 +527,14 @@ test "vector reduce operation" {
switch (@typeInfo(TX)) {
.Int, .Bool => expectEqual(expected, r),
.Float => {
- if (math.isNan(expected) != math.isNan(r)) {
- std.debug.panic("unexpected NaN value!\n", .{});
+ const expected_nan = math.isNan(expected);
+ const got_nan = math.isNan(r);
+
+ if (expected_nan and got_nan) {
+ // Do this check explicitly as two NaN values are never
+ // equal.
} else {
- expectWithinEpsilon(expected, r, 0.001);
+ expectApproxEqRel(expected, r, math.sqrt(math.epsilon(TX)));
}
},
else => unreachable,
diff --git a/test/stage2/cbe.zig b/test/stage2/cbe.zig
index e9082f57fa..8a8a8ca224 100644
--- a/test/stage2/cbe.zig
+++ b/test/stage2/cbe.zig
@@ -51,7 +51,7 @@ pub fn addCases(ctx: *TestContext) !void {
\\ _ = printf("Hello, %s!\n", "world");
\\ return 0;
\\}
- , "Hello, world!\n");
+ , "Hello, world!" ++ std.cstr.line_sep);
}
{
diff --git a/test/stage2/wasm.zig b/test/stage2/wasm.zig
index 06ede2d735..51df6bccf0 100644
--- a/test/stage2/wasm.zig
+++ b/test/stage2/wasm.zig
@@ -175,6 +175,41 @@ pub fn addCases(ctx: *TestContext) !void {
\\ return i;
\\}
, "31\n");
+
+ case.addCompareOutput(
+ \\export fn _start() void {
+ \\ assert(foo(true) != @as(i32, 30));
+ \\}
+ \\
+ \\fn assert(ok: bool) void {
+ \\ if (!ok) unreachable;
+ \\}
+ \\
+ \\fn foo(ok: bool) i32 {
+ \\ const x = if(ok) @as(i32, 20) else @as(i32, 10);
+ \\ return x;
+ \\}
+ , "");
+
+ case.addCompareOutput(
+ \\export fn _start() void {
+ \\ assert(foo(false) == @as(i32, 20));
+ \\ assert(foo(true) == @as(i32, 30));
+ \\}
+ \\
+ \\fn assert(ok: bool) void {
+ \\ if (!ok) unreachable;
+ \\}
+ \\
+ \\fn foo(ok: bool) i32 {
+ \\ const val: i32 = blk: {
+ \\ var x: i32 = 1;
+ \\ if (!ok) break :blk x + @as(i32, 9);
+ \\ break :blk x + @as(i32, 19);
+ \\ };
+ \\ return val + 10;
+ \\}
+ , "");
}
{
diff --git a/test/standalone.zig b/test/standalone.zig
index 3ad0659f09..d8c08a6b9c 100644
--- a/test/standalone.zig
+++ b/test/standalone.zig
@@ -9,7 +9,10 @@ pub fn addCases(cases: *tests.StandaloneContext) void {
cases.add("test/standalone/main_return_error/error_u8.zig");
cases.add("test/standalone/main_return_error/error_u8_non_zero.zig");
cases.addBuildFile("test/standalone/main_pkg_path/build.zig");
- cases.addBuildFile("test/standalone/shared_library/build.zig");
+ if (std.Target.current.os.tag != .macos) {
+ // TODO zld cannot link shared libraries yet.
+ cases.addBuildFile("test/standalone/shared_library/build.zig");
+ }
cases.addBuildFile("test/standalone/mix_o_files/build.zig");
cases.addBuildFile("test/standalone/global_linkage/build.zig");
cases.addBuildFile("test/standalone/static_c_lib/build.zig");
diff --git a/test/standalone/mix_o_files/base64.zig b/test/standalone/mix_o_files/base64.zig
index 7ded9824a0..b5cfcaba50 100644
--- a/test/standalone/mix_o_files/base64.zig
+++ b/test/standalone/mix_o_files/base64.zig
@@ -3,9 +3,9 @@ const base64 = @import("std").base64;
export fn decode_base_64(dest_ptr: [*]u8, dest_len: usize, source_ptr: [*]const u8, source_len: usize) usize {
const src = source_ptr[0..source_len];
const dest = dest_ptr[0..dest_len];
- const base64_decoder = base64.standard_decoder_unsafe;
- const decoded_size = base64_decoder.calcSize(src);
- base64_decoder.decode(dest[0..decoded_size], src);
+ const base64_decoder = base64.standard.Decoder;
+ const decoded_size = base64_decoder.calcSizeForSlice(src) catch unreachable;
+ base64_decoder.decode(dest[0..decoded_size], src) catch unreachable;
return decoded_size;
}
diff --git a/test/translate_c.zig b/test/translate_c.zig
index 47d7c5d9eb..54bb468cf9 100644
--- a/test/translate_c.zig
+++ b/test/translate_c.zig
@@ -3,6 +3,28 @@ const std = @import("std");
const CrossTarget = std.zig.CrossTarget;
pub fn addCases(cases: *tests.TranslateCContext) void {
+ cases.add("unnamed child types of typedef receive typedef's name",
+ \\typedef enum {
+ \\ FooA,
+ \\ FooB,
+ \\} Foo;
+ \\typedef struct {
+ \\ int a, b;
+ \\} Bar;
+ , &[_][]const u8{
+ \\pub const Foo = extern enum(c_int) {
+ \\ A,
+ \\ B,
+ \\ _,
+ \\};
+ \\pub const FooA = @enumToInt(Foo.A);
+ \\pub const FooB = @enumToInt(Foo.B);
+ \\pub const Bar = extern struct {
+ \\ a: c_int,
+ \\ b: c_int,
+ \\};
+ });
+
cases.add("if as while stmt has semicolon",
\\void foo() {
\\ while (1) if (1) {
@@ -218,9 +240,8 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\} Bar;
, &[_][]const u8{
\\source.h:1:9: warning: struct demoted to opaque type - unable to translate type of field foo
- \\const struct_unnamed_1 = opaque {};
- \\pub const Foo = struct_unnamed_1;
- \\const struct_unnamed_2 = extern struct {
+ \\pub const Foo = opaque {};
+ \\pub const Bar = extern struct {
\\ bar: ?*Foo,
\\};
});
@@ -519,17 +540,16 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\} outer;
\\void foo(outer *x) { x->y = x->x; }
, &[_][]const u8{
- \\const struct_unnamed_3 = extern struct {
+ \\const struct_unnamed_2 = extern struct {
\\ y: c_int,
\\};
- \\const union_unnamed_2 = extern union {
+ \\const union_unnamed_1 = extern union {
\\ x: u8,
- \\ unnamed_0: struct_unnamed_3,
+ \\ unnamed_0: struct_unnamed_2,
\\};
- \\const struct_unnamed_1 = extern struct {
- \\ unnamed_0: union_unnamed_2,
+ \\pub const outer = extern struct {
+ \\ unnamed_0: union_unnamed_1,
\\};
- \\pub const outer = struct_unnamed_1;
\\pub export fn foo(arg_x: [*c]outer) void {
\\ var x = arg_x;
\\ x.*.unnamed_0.unnamed_0.y = @bitCast(c_int, @as(c_uint, x.*.unnamed_0.x));
@@ -565,21 +585,20 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\struct {int x,y;} s2 = {.y = 2, .x=1};
\\foo s3 = { 123 };
, &[_][]const u8{
- \\const struct_unnamed_1 = extern struct {
+ \\pub const foo = extern struct {
\\ x: c_int,
\\};
- \\pub const foo = struct_unnamed_1;
- \\const struct_unnamed_2 = extern struct {
+ \\const struct_unnamed_1 = extern struct {
\\ x: f64,
\\ y: f64,
\\ z: f64,
\\};
- \\pub export var s0: struct_unnamed_2 = struct_unnamed_2{
+ \\pub export var s0: struct_unnamed_1 = struct_unnamed_1{
\\ .x = 1.2,
\\ .y = 1.3,
\\ .z = 0,
\\};
- \\const struct_unnamed_3 = extern struct {
+ \\const struct_unnamed_2 = extern struct {
\\ sec: c_int,
\\ min: c_int,
\\ hour: c_int,
@@ -587,7 +606,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\ mon: c_int,
\\ year: c_int,
\\};
- \\pub export var s1: struct_unnamed_3 = struct_unnamed_3{
+ \\pub export var s1: struct_unnamed_2 = struct_unnamed_2{
\\ .sec = @as(c_int, 30),
\\ .min = @as(c_int, 15),
\\ .hour = @as(c_int, 17),
@@ -595,11 +614,11 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\ .mon = @as(c_int, 12),
\\ .year = @as(c_int, 2014),
\\};
- \\const struct_unnamed_4 = extern struct {
+ \\const struct_unnamed_3 = extern struct {
\\ x: c_int,
\\ y: c_int,
\\};
- \\pub export var s2: struct_unnamed_4 = struct_unnamed_4{
+ \\pub export var s2: struct_unnamed_3 = struct_unnamed_3{
\\ .x = @as(c_int, 1),
\\ .y = @as(c_int, 2),
\\};
@@ -745,14 +764,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\ static const char v2[] = "2.2.2";
\\}
, &[_][]const u8{
- \\const v2: [6]u8 = [6]u8{
- \\ '2',
- \\ '.',
- \\ '2',
- \\ '.',
- \\ '2',
- \\ 0,
- \\};
+ \\const v2: [5:0]u8 = "2.2.2".*;
\\pub export fn foo() void {}
});
@@ -1600,30 +1612,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\static char arr1[] = "hello";
\\char arr2[] = "hello";
, &[_][]const u8{
- \\pub export var arr0: [6]u8 = [6]u8{
- \\ 'h',
- \\ 'e',
- \\ 'l',
- \\ 'l',
- \\ 'o',
- \\ 0,
- \\};
- \\pub var arr1: [6]u8 = [6]u8{
- \\ 'h',
- \\ 'e',
- \\ 'l',
- \\ 'l',
- \\ 'o',
- \\ 0,
- \\};
- \\pub export var arr2: [6]u8 = [6]u8{
- \\ 'h',
- \\ 'e',
- \\ 'l',
- \\ 'l',
- \\ 'o',
- \\ 0,
- \\};
+ \\pub export var arr0: [5:0]u8 = "hello".*;
+ \\pub var arr1: [5:0]u8 = "hello".*;
+ \\pub export var arr2: [5:0]u8 = "hello".*;
});
cases.add("array initializer expr",
@@ -1667,37 +1658,36 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\ p,
\\};
, &[_][]const u8{
- \\const enum_unnamed_1 = extern enum(c_int) {
+ \\pub const d = extern enum(c_int) {
\\ a,
\\ b,
\\ c,
\\ _,
\\};
- \\pub const a = @enumToInt(enum_unnamed_1.a);
- \\pub const b = @enumToInt(enum_unnamed_1.b);
- \\pub const c = @enumToInt(enum_unnamed_1.c);
- \\pub const d = enum_unnamed_1;
- \\const enum_unnamed_2 = extern enum(c_int) {
+ \\pub const a = @enumToInt(d.a);
+ \\pub const b = @enumToInt(d.b);
+ \\pub const c = @enumToInt(d.c);
+ \\const enum_unnamed_1 = extern enum(c_int) {
\\ e = 0,
\\ f = 4,
\\ g = 5,
\\ _,
\\};
- \\pub const e = @enumToInt(enum_unnamed_2.e);
- \\pub const f = @enumToInt(enum_unnamed_2.f);
- \\pub const g = @enumToInt(enum_unnamed_2.g);
- \\pub export var h: enum_unnamed_2 = @intToEnum(enum_unnamed_2, e);
- \\const enum_unnamed_3 = extern enum(c_int) {
+ \\pub const e = @enumToInt(enum_unnamed_1.e);
+ \\pub const f = @enumToInt(enum_unnamed_1.f);
+ \\pub const g = @enumToInt(enum_unnamed_1.g);
+ \\pub export var h: enum_unnamed_1 = @intToEnum(enum_unnamed_1, e);
+ \\const enum_unnamed_2 = extern enum(c_int) {
\\ i,
\\ j,
\\ k,
\\ _,
\\};
- \\pub const i = @enumToInt(enum_unnamed_3.i);
- \\pub const j = @enumToInt(enum_unnamed_3.j);
- \\pub const k = @enumToInt(enum_unnamed_3.k);
+ \\pub const i = @enumToInt(enum_unnamed_2.i);
+ \\pub const j = @enumToInt(enum_unnamed_2.j);
+ \\pub const k = @enumToInt(enum_unnamed_2.k);
\\pub const struct_Baz = extern struct {
- \\ l: enum_unnamed_3,
+ \\ l: enum_unnamed_2,
\\ m: d,
\\};
\\pub const enum_i = extern enum(c_int) {
@@ -1962,7 +1952,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
, &[_][]const u8{
\\pub export fn foo() c_int {
\\ var a: c_int = 5;
- \\ while (true) a = 2;
+ \\ while (true) {
+ \\ a = 2;
+ \\ }
\\ while (true) {
\\ var a_1: c_int = 4;
\\ a_1 = 9;
@@ -1975,7 +1967,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\ var a_1: c_int = 2;
\\ a_1 = 12;
\\ }
- \\ while (true) a = 7;
+ \\ while (true) {
+ \\ a = 7;
+ \\ }
\\ return 0;
\\}
});
@@ -2036,7 +2030,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\}
, &[_][]const u8{
\\pub export fn bar() c_int {
- \\ if ((if (true) @as(c_int, 5) else if (true) @as(c_int, 4) else @as(c_int, 6)) != 0) _ = @as(c_int, 2);
+ \\ if ((if (true) @as(c_int, 5) else if (true) @as(c_int, 4) else @as(c_int, 6)) != 0) {
+ \\ _ = @as(c_int, 2);
+ \\ }
\\ return if (true) @as(c_int, 5) else if (true) @as(c_int, 4) else @as(c_int, 6);
\\}
});
@@ -2417,7 +2413,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\pub const yes = [*c]u8;
\\pub export fn foo() void {
\\ var a: yes = undefined;
- \\ if (a != null) _ = @as(c_int, 2);
+ \\ if (a != null) {
+ \\ _ = @as(c_int, 2);
+ \\ }
\\}
});
@@ -2456,7 +2454,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\ b: c_int,
\\};
\\pub extern var a: struct_Foo;
- \\pub export var b: f32 = 2;
+ \\pub export var b: f32 = 2.0;
\\pub export fn foo() void {
\\ var c: [*c]struct_Foo = undefined;
\\ _ = a.b;
@@ -2768,7 +2766,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\ var a = arg_a;
\\ var i: c_int = 0;
\\ while (a > @bitCast(c_uint, @as(c_int, 0))) {
- \\ a >>= @intCast(@import("std").math.Log2Int(c_int), 1);
+ \\ a >>= @intCast(@import("std").math.Log2Int(c_int), @as(c_int, 1));
\\ }
\\ return i;
\\}
@@ -2788,7 +2786,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\ var a = arg_a;
\\ var i: c_int = 0;
\\ while (a > @bitCast(c_uint, @as(c_int, 0))) {
- \\ a >>= @intCast(@import("std").math.Log2Int(c_int), 1);
+ \\ a >>= @intCast(@import("std").math.Log2Int(c_int), @as(c_int, 1));
\\ }
\\ return i;
\\}
@@ -3020,17 +3018,17 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\pub extern fn fn_bool(x: bool) void;
\\pub extern fn fn_ptr(x: ?*c_void) void;
\\pub export fn call() void {
- \\ fn_int(@floatToInt(c_int, 3));
- \\ fn_int(@floatToInt(c_int, 3));
- \\ fn_int(@floatToInt(c_int, 3));
+ \\ fn_int(@floatToInt(c_int, 3.0));
+ \\ fn_int(@floatToInt(c_int, 3.0));
+ \\ fn_int(@floatToInt(c_int, 3.0));
\\ fn_int(@as(c_int, 1094861636));
\\ fn_f32(@intToFloat(f32, @as(c_int, 3)));
\\ fn_f64(@intToFloat(f64, @as(c_int, 3)));
\\ fn_char(@bitCast(u8, @truncate(i8, @as(c_int, '3'))));
\\ fn_char(@bitCast(u8, @truncate(i8, @as(c_int, '\x01'))));
\\ fn_char(@bitCast(u8, @truncate(i8, @as(c_int, 0))));
- \\ fn_f32(3);
- \\ fn_f64(3);
+ \\ fn_f32(3.0);
+ \\ fn_f64(3.0);
\\ fn_bool(@as(c_int, 123) != 0);
\\ fn_bool(@as(c_int, 0) != 0);
\\ fn_bool(@ptrToInt(fn_int) != 0);
@@ -3418,4 +3416,56 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\pub const MAY_NEED_PROMOTION_HEX = @import("std").meta.promoteIntLiteral(c_int, 0x80000000, .hexadecimal);
\\pub const MAY_NEED_PROMOTION_OCT = @import("std").meta.promoteIntLiteral(c_int, 0o20000000000, .octal);
});
+
+ // See __builtin_alloca_with_align comment in std.c.builtins
+ cases.add("demote un-implemented builtins",
+ \\#define FOO(X) __builtin_alloca_with_align((X), 8)
+ , &[_][]const u8{
+ \\pub const FOO = @compileError("TODO implement function '__builtin_alloca_with_align' in std.c.builtins");
+ });
+
+ cases.add("null sentinel arrays when initialized from string literal. Issue #8256",
+ \\#include <stdint.h>
+ \\char zero[0] = "abc";
+ \\uint32_t zero_w[0] = U"💯💯💯";
+ \\char empty_incomplete[] = "";
+ \\uint32_t empty_incomplete_w[] = U"";
+ \\char empty_constant[100] = "";
+ \\uint32_t empty_constant_w[100] = U"";
+ \\char incomplete[] = "abc";
+ \\uint32_t incomplete_w[] = U"💯💯💯";
+ \\char truncated[1] = "abc";
+ \\uint32_t truncated_w[1] = U"💯💯💯";
+ \\char extend[5] = "a";
+ \\uint32_t extend_w[5] = U"💯";
+ \\char no_null[3] = "abc";
+ \\uint32_t no_null_w[3] = U"💯💯💯";
+ , &[_][]const u8{
+ \\pub export var zero: [0]u8 = [0]u8{};
+ \\pub export var zero_w: [0]u32 = [0]u32{};
+ \\pub export var empty_incomplete: [1]u8 = [1]u8{0} ** 1;
+ \\pub export var empty_incomplete_w: [1]u32 = [1]u32{0} ** 1;
+ \\pub export var empty_constant: [100]u8 = [1]u8{0} ** 100;
+ \\pub export var empty_constant_w: [100]u32 = [1]u32{0} ** 100;
+ \\pub export var incomplete: [3:0]u8 = "abc".*;
+ \\pub export var incomplete_w: [3:0]u32 = [3:0]u32{
+ \\ '\u{1f4af}',
+ \\ '\u{1f4af}',
+ \\ '\u{1f4af}',
+ \\};
+ \\pub export var truncated: [1]u8 = "abc"[0..1].*;
+ \\pub export var truncated_w: [1]u32 = [1]u32{
+ \\ '\u{1f4af}',
+ \\};
+ \\pub export var extend: [5]u8 = "a"[0..1].* ++ [1]u8{0} ** 4;
+ \\pub export var extend_w: [5]u32 = [1]u32{
+ \\ '\u{1f4af}',
+ \\} ++ [1]u32{0} ** 4;
+ \\pub export var no_null: [3]u8 = "abc".*;
+ \\pub export var no_null_w: [3]u32 = [3]u32{
+ \\ '\u{1f4af}',
+ \\ '\u{1f4af}',
+ \\ '\u{1f4af}',
+ \\};
+ });
}