authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-07-11 20:25:35-04:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2022-07-11 20:25:35-04:00
logdc815e5e8f194a03988624a6bf7e739ddfe0d3b4
treeb464bf4b82f344c7b20cf9af212b95c0a42bc893
parent8b3f15f21824e77e776336d8be5832502946621b
parent122c76a1670e4b925ccdabaa771f59e5df6d43aa
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #12075 from Vexu/stage2-validate-extern

Stage2 validate extern types

19 files changed, 313 insertions(+), 116 deletions(-)

lib/compiler_rt/multi3.zig+2-2
......@@ -59,12 +59,12 @@ const twords = extern union {
5959 s: S,
6060
6161 const S = if (native_endian == .Little)
62 struct {
62 extern struct {
6363 low: u64,
6464 high: u64,
6565 }
6666 else
67 struct {
67 extern struct {
6868 high: u64,
6969 low: u64,
7070 };
lib/compiler_rt/shift.zig+2-2
......@@ -31,9 +31,9 @@ fn Dwords(comptime T: type, comptime signed_half: bool) type {
3131
3232 all: T,
3333 s: if (native_endian == .Little)
34 struct { low: HalfT, high: HalfT }
34 extern struct { low: HalfT, high: HalfT }
3535 else
36 struct { high: HalfT, low: HalfT },
36 extern struct { high: HalfT, low: HalfT },
3737 };
3838}
3939
lib/std/c/haiku.zig+2-2
......@@ -30,8 +30,8 @@ pub extern "c" fn _kern_get_current_team() i32;
3030pub const sem_t = extern struct {
3131 type: i32,
3232 u: extern union {
33 named_sem_id: ?i32,
34 unnamed_sem: ?i32,
33 named_sem_id: i32,
34 unnamed_sem: i32,
3535 },
3636 padding: [2]i32,
3737};
lib/std/start.zig+1-1
......@@ -108,7 +108,7 @@ fn callMain2() noreturn {
108108 exit2(0);
109109}
110110
111fn wasiMain2() noreturn {
111fn wasiMain2() callconv(.C) noreturn {
112112 switch (@typeInfo(@typeInfo(@TypeOf(root.main)).Fn.return_type.?)) {
113113 .Void => {
114114 root.main();
src/Sema.zig+177-9
......@@ -4740,12 +4740,19 @@ pub fn analyzeExport(
47404740
47414741 try mod.ensureDeclAnalyzed(exported_decl_index);
47424742 const exported_decl = mod.declPtr(exported_decl_index);
4743 // TODO run the same checks as we do for C ABI struct fields
4744 switch (exported_decl.ty.zigTypeTag()) {
4745 .Fn, .Int, .Enum, .Struct, .Union, .Array, .Float, .Pointer, .Optional => {},
4746 else => return sema.fail(block, src, "unable to export type '{}'", .{
4747 exported_decl.ty.fmt(sema.mod),
4748 }),
4743
4744 if (!(try sema.validateExternType(exported_decl.ty, .other))) {
4745 const msg = msg: {
4746 const msg = try sema.errMsg(block, src, "unable to export type '{}'", .{exported_decl.ty.fmt(sema.mod)});
4747 errdefer msg.destroy(sema.gpa);
4748
4749 const src_decl = sema.mod.declPtr(block.src_decl);
4750 try sema.explainWhyTypeIsNotExtern(block, src, msg, src.toSrcLoc(src_decl), exported_decl.ty, .other);
4751
4752 try sema.addDeclaredHereNote(msg, exported_decl.ty);
4753 break :msg msg;
4754 };
4755 return sema.failWithOwnedErrorMsg(block, msg);
47494756 }
47504757
47514758 const gpa = mod.gpa;
......@@ -13799,7 +13806,20 @@ fn validatePtrTy(sema: *Sema, block: *Block, elem_src: LazySrcLoc, ty: Type) Com
1379913806 } else if (ptr_info.size == .Many and pointee_tag == .Opaque) {
1380013807 return sema.fail(block, elem_src, "unknown-length pointer to opaque not allowed", .{});
1380113808 } else if (ptr_info.size == .C) {
13802 // TODO check extern type
13809 const elem_ty = ptr_info.pointee_type;
13810 if (!(try sema.validateExternType(elem_ty, .other))) {
13811 const msg = msg: {
13812 const msg = try sema.errMsg(block, elem_src, "C pointers cannot point to non-C-ABI-compatible type '{}'", .{elem_ty.fmt(sema.mod)});
13813 errdefer msg.destroy(sema.gpa);
13814
13815 const src_decl = sema.mod.declPtr(block.src_decl);
13816 try sema.explainWhyTypeIsNotExtern(block, elem_src, msg, elem_src.toSrcLoc(src_decl), elem_ty, .other);
13817
13818 try sema.addDeclaredHereNote(msg, elem_ty);
13819 break :msg msg;
13820 };
13821 return sema.failWithOwnedErrorMsg(block, msg);
13822 }
1380313823 if (pointee_tag == .Opaque) {
1380413824 return sema.fail(block, elem_src, "C pointers cannot point to opaque types", .{});
1380513825 }
......@@ -18098,10 +18118,12 @@ fn explainWhyTypeIsComptime(
1809818118 .NoReturn,
1809918119 .Undefined,
1810018120 .Null,
18101 .Opaque,
18102 .Optional,
1810318121 => return,
1810418122
18123 .Opaque => {
18124 try mod.errNoteNonLazy(src_loc, msg, "opaque type '{}' has undefined size", .{ty.fmt(sema.mod)});
18125 },
18126
1810518127 .Array, .Vector => {
1810618128 try sema.explainWhyTypeIsComptime(block, src, msg, src_loc, ty.elemType());
1810718129 },
......@@ -18124,6 +18146,10 @@ fn explainWhyTypeIsComptime(
1812418146 try sema.explainWhyTypeIsComptime(block, src, msg, src_loc, ty.elemType());
1812518147 },
1812618148
18149 .Optional => {
18150 var buf: Type.Payload.ElemType = undefined;
18151 try sema.explainWhyTypeIsComptime(block, src, msg, src_loc, ty.optionalChild(&buf));
18152 },
1812718153 .ErrorUnion => {
1812818154 try sema.explainWhyTypeIsComptime(block, src, msg, src_loc, ty.errorUnionPayload());
1812918155 },
......@@ -18163,6 +18189,120 @@ fn explainWhyTypeIsComptime(
1816318189 }
1816418190}
1816518191
18192const ExternPosition = enum {
18193 ret_ty,
18194 param_ty,
18195 union_field,
18196 other,
18197};
18198
18199fn validateExternType(sema: *Sema, ty: Type, position: ExternPosition) CompileError!bool {
18200 switch (ty.zigTypeTag()) {
18201 .Type,
18202 .ComptimeFloat,
18203 .ComptimeInt,
18204 .EnumLiteral,
18205 .Undefined,
18206 .Null,
18207 .ErrorUnion,
18208 .ErrorSet,
18209 .BoundFn,
18210 .Frame,
18211 => return false,
18212 .Void => return position == .union_field,
18213 .NoReturn => return position == .ret_ty,
18214 .Opaque,
18215 .Bool,
18216 .Float,
18217 .Pointer,
18218 .AnyFrame,
18219 => return true,
18220 .Int => switch (ty.intInfo(sema.mod.getTarget()).bits) {
18221 8, 16, 32, 64, 128 => return true,
18222 else => return false,
18223 },
18224 .Fn => return !ty.fnCallingConventionAllowsZigTypes(),
18225 .Enum => {
18226 var buf: Type.Payload.Bits = undefined;
18227 return sema.validateExternType(ty.intTagType(&buf), position);
18228 },
18229 .Struct, .Union => switch (ty.containerLayout()) {
18230 .Extern, .Packed => return true,
18231 else => return false,
18232 },
18233 .Array => {
18234 if (position == .ret_ty or position == .param_ty) return false;
18235 return sema.validateExternType(ty.elemType2(), .other);
18236 },
18237 .Vector => return sema.validateExternType(ty.elemType2(), .other),
18238 .Optional => return ty.isPtrLikeOptional(),
18239 }
18240}
18241
18242fn explainWhyTypeIsNotExtern(
18243 sema: *Sema,
18244 block: *Block,
18245 src: LazySrcLoc,
18246 msg: *Module.ErrorMsg,
18247 src_loc: Module.SrcLoc,
18248 ty: Type,
18249 position: ExternPosition,
18250) CompileError!void {
18251 const mod = sema.mod;
18252 switch (ty.zigTypeTag()) {
18253 .Opaque,
18254 .Bool,
18255 .Float,
18256 .Pointer,
18257 .AnyFrame,
18258 => return,
18259
18260 .Type,
18261 .ComptimeFloat,
18262 .ComptimeInt,
18263 .EnumLiteral,
18264 .Undefined,
18265 .Null,
18266 .ErrorUnion,
18267 .ErrorSet,
18268 .BoundFn,
18269 .Frame,
18270 => return,
18271
18272 .Void => try mod.errNoteNonLazy(src_loc, msg, "'void' is a zero bit type; for C 'void' use 'anyopaque'", .{}),
18273 .NoReturn => try mod.errNoteNonLazy(src_loc, msg, "'noreturn' is only allowed as a return type", .{}),
18274 .Int => if (ty.intInfo(sema.mod.getTarget()).bits > 128) {
18275 try mod.errNoteNonLazy(src_loc, msg, "only integers with less than 128 bits are extern compatible", .{});
18276 } else {
18277 try mod.errNoteNonLazy(src_loc, msg, "only integers with power of two bits are extern compatible", .{});
18278 },
18279 .Fn => switch (ty.fnCallingConvention()) {
18280 .Unspecified => try mod.errNoteNonLazy(src_loc, msg, "extern function must specify calling convention", .{}),
18281 .Async => try mod.errNoteNonLazy(src_loc, msg, "async function cannot be extern", .{}),
18282 .Inline => try mod.errNoteNonLazy(src_loc, msg, "inline function cannot be extern", .{}),
18283 else => return,
18284 },
18285 .Enum => {
18286 var buf: Type.Payload.Bits = undefined;
18287 const tag_ty = ty.intTagType(&buf);
18288 try mod.errNoteNonLazy(src_loc, msg, "enum tag type '{}' is not extern compatible", .{tag_ty.fmt(sema.mod)});
18289 try sema.explainWhyTypeIsNotExtern(block, src, msg, src_loc, tag_ty, position);
18290 },
18291 .Struct => try mod.errNoteNonLazy(src_loc, msg, "only structs with packed or extern layout are extern compatible", .{}),
18292 .Union => try mod.errNoteNonLazy(src_loc, msg, "only unions with packed or extern layout are extern compatible", .{}),
18293 .Array => {
18294 if (position == .ret_ty) {
18295 try mod.errNoteNonLazy(src_loc, msg, "arrays are not allowed as a return type", .{});
18296 } else if (position == .param_ty) {
18297 try mod.errNoteNonLazy(src_loc, msg, "arrays are not allowed as a parameter type", .{});
18298 }
18299 try sema.explainWhyTypeIsNotExtern(block, src, msg, src_loc, ty.elemType2(), position);
18300 },
18301 .Vector => try sema.explainWhyTypeIsNotExtern(block, src, msg, src_loc, ty.elemType2(), position),
18302 .Optional => try mod.errNoteNonLazy(src_loc, msg, "only pointer like optionals are extern compatible", .{}),
18303 }
18304}
18305
1816618306pub const PanicId = enum {
1816718307 unreach,
1816818308 unwrap_null,
......@@ -24006,6 +24146,20 @@ fn resolveStructFully(
2400624146 struct_obj.status = .fully_resolved_wip;
2400724147 for (struct_obj.fields.values()) |field| {
2400824148 try sema.resolveTypeFully(block, src, field.ty);
24149
24150 if (struct_obj.layout == .Extern and !(try sema.validateExternType(field.ty, .other))) {
24151 const msg = msg: {
24152 const msg = try sema.errMsg(block, src, "extern structs cannot contain fields of type '{}'", .{field.ty.fmt(sema.mod)});
24153 errdefer msg.destroy(sema.gpa);
24154
24155 const src_decl = sema.mod.declPtr(block.src_decl);
24156 try sema.explainWhyTypeIsNotExtern(block, src, msg, src.toSrcLoc(src_decl), field.ty, .other);
24157
24158 try sema.addDeclaredHereNote(msg, field.ty);
24159 break :msg msg;
24160 };
24161 return sema.failWithOwnedErrorMsg(block, msg);
24162 }
2400924163 }
2401024164 struct_obj.status = .fully_resolved;
2401124165 }
......@@ -24039,6 +24193,20 @@ fn resolveUnionFully(
2403924193 union_obj.status = .fully_resolved_wip;
2404024194 for (union_obj.fields.values()) |field| {
2404124195 try sema.resolveTypeFully(block, src, field.ty);
24196
24197 if (union_obj.layout == .Extern and !(try sema.validateExternType(field.ty, .union_field))) {
24198 const msg = msg: {
24199 const msg = try sema.errMsg(block, src, "extern unions cannot contain fields of type '{}'", .{field.ty.fmt(sema.mod)});
24200 errdefer msg.destroy(sema.gpa);
24201
24202 const src_decl = sema.mod.declPtr(block.src_decl);
24203 try sema.explainWhyTypeIsNotExtern(block, src, msg, src.toSrcLoc(src_decl), field.ty, .union_field);
24204
24205 try sema.addDeclaredHereNote(msg, field.ty);
24206 break :msg msg;
24207 };
24208 return sema.failWithOwnedErrorMsg(block, msg);
24209 }
2404224210 }
2404324211 union_obj.status = .fully_resolved;
2404424212 }
src/type.zig+8-1
......@@ -3935,7 +3935,6 @@ pub const Type = extern union {
39353935
39363936 /// Returns true if the type is optional and would be lowered to a single pointer
39373937 /// address value, using 0 for null. Note that this returns true for C pointers.
3938 /// See also `hasOptionalRepr`.
39393938 pub fn isPtrLikeOptional(self: Type) bool {
39403939 switch (self.tag()) {
39413940 .optional_single_const_pointer,
......@@ -4630,6 +4629,14 @@ pub const Type = extern union {
46304629 };
46314630 }
46324631
4632 /// Asserts the type is a function.
4633 pub fn fnCallingConventionAllowsZigTypes(self: Type) bool {
4634 return switch (self.fnCallingConvention()) {
4635 .Unspecified, .Async, .Inline, .PtxKernel => true,
4636 else => false,
4637 };
4638 }
4639
46334640 /// Asserts the type is a function.
46344641 pub fn fnIsVarArgs(self: Type) bool {
46354642 return switch (self.tag()) {
test/behavior/union.zig+4-3
......@@ -84,18 +84,19 @@ test "comptime union field access" {
8484
8585const FooExtern = extern union {
8686 int: i32,
87 str: struct {
88 slice: []const u8,
87 str: extern struct {
88 slice: [*:0]const u8,
8989 },
9090};
9191
9292test "basic extern unions" {
93 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
9394 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
9495
9596 var foo = FooExtern{ .int = 1 };
9697 try expect(foo.int == 1);
9798 foo.str.slice = "Well";
98 try expect(std.mem.eql(u8, foo.str.slice, "Well"));
99 try expect(std.mem.eql(u8, std.mem.sliceTo(foo.str.slice, 0), "Well"));
99100}
100101
101102const ExternPtrOrInt = extern union {
test/cases/compile_errors/c_pointer_to_void.zig created+11
......@@ -0,0 +1,11 @@
1export fn entry() void {
2 var a: [*c]void = undefined;
3 _ = a;
4}
5
6// error
7// backend=stage2
8// target=native
9//
10// :1:1: error: C pointers cannot point to non-C-ABI-compatible type 'void'
11// :1:1: note: 'void' is a zero bit type; for C 'void' use 'anyopaque'
test/cases/compile_errors/exported_enum_without_explicit_integer_tag_type.zig created+18
......@@ -0,0 +1,18 @@
1const E = enum { one, two };
2comptime {
3 @export(E, .{ .name = "E" });
4}
5const e: E = .two;
6comptime {
7 @export(e, .{ .name = "e" });
8}
9
10// error
11// backend=stage2
12// target=native
13//
14// :3:5: error: unable to export type 'type'
15// :7:5: error: unable to export type 'tmp.E'
16// :7:5: note: enum tag type 'u1' is not extern compatible
17// :7:5: note: only integers with power of two bits are extern compatible
18// :1:11: note: enum declared here
test/cases/compile_errors/extern_struct_with_extern-compatible_but_inferred_integer_tag_type.zig created+45
......@@ -0,0 +1,45 @@
1pub const E = enum {
2@"0",@"1",@"2",@"3",@"4",@"5",@"6",@"7",@"8",@"9",@"10",@"11",@"12",
3@"13",@"14",@"15",@"16",@"17",@"18",@"19",@"20",@"21",@"22",@"23",
4@"24",@"25",@"26",@"27",@"28",@"29",@"30",@"31",@"32",@"33",@"34",
5@"35",@"36",@"37",@"38",@"39",@"40",@"41",@"42",@"43",@"44",@"45",
6@"46",@"47",@"48",@"49",@"50",@"51",@"52",@"53",@"54",@"55",@"56",
7@"57",@"58",@"59",@"60",@"61",@"62",@"63",@"64",@"65",@"66",@"67",
8@"68",@"69",@"70",@"71",@"72",@"73",@"74",@"75",@"76",@"77",@"78",
9@"79",@"80",@"81",@"82",@"83",@"84",@"85",@"86",@"87",@"88",@"89",
10@"90",@"91",@"92",@"93",@"94",@"95",@"96",@"97",@"98",@"99",@"100",
11@"101",@"102",@"103",@"104",@"105",@"106",@"107",@"108",@"109",
12@"110",@"111",@"112",@"113",@"114",@"115",@"116",@"117",@"118",
13@"119",@"120",@"121",@"122",@"123",@"124",@"125",@"126",@"127",
14@"128",@"129",@"130",@"131",@"132",@"133",@"134",@"135",@"136",
15@"137",@"138",@"139",@"140",@"141",@"142",@"143",@"144",@"145",
16@"146",@"147",@"148",@"149",@"150",@"151",@"152",@"153",@"154",
17@"155",@"156",@"157",@"158",@"159",@"160",@"161",@"162",@"163",
18@"164",@"165",@"166",@"167",@"168",@"169",@"170",@"171",@"172",
19@"173",@"174",@"175",@"176",@"177",@"178",@"179",@"180",@"181",
20@"182",@"183",@"184",@"185",@"186",@"187",@"188",@"189",@"190",
21@"191",@"192",@"193",@"194",@"195",@"196",@"197",@"198",@"199",
22@"200",@"201",@"202",@"203",@"204",@"205",@"206",@"207",@"208",
23@"209",@"210",@"211",@"212",@"213",@"214",@"215",@"216",@"217",
24@"218",@"219",@"220",@"221",@"222",@"223",@"224",@"225",@"226",
25@"227",@"228",@"229",@"230",@"231",@"232",@"233",@"234",@"235",
26@"236",@"237",@"238",@"239",@"240",@"241",@"242",@"243",@"244",
27@"245",@"246",@"247",@"248",@"249",@"250",@"251",@"252",@"253",
28@"254",@"255", @"256"
29};
30pub const S = extern struct {
31 e: E,
32};
33export fn entry() void {
34 const s: S = undefined;
35 _ = s;
36}
37
38// error
39// backend=stage2
40// target=native
41//
42// :33:8: error: extern structs cannot contain fields of type 'tmp.E'
43// :33:8: note: enum tag type 'u9' is not extern compatible
44// :33:8: note: only integers with power of two bits are extern compatible
45// :1:15: note: enum declared here
test/cases/compile_errors/extern_struct_with_non-extern-compatible_integer_tag_type.zig created+17
......@@ -0,0 +1,17 @@
1pub const E = enum(u31) { A, B, C };
2pub const S = extern struct {
3 e: E,
4};
5export fn entry() void {
6 const s: S = undefined;
7 _ = s;
8}
9
10// error
11// backend=stage2
12// target=native
13//
14// :5:8: error: extern structs cannot contain fields of type 'tmp.E'
15// :5:8: note: enum tag type 'u31' is not extern compatible
16// :5:8: note: only integers with power of two bits are extern compatible
17// :1:15: note: enum declared here
test/cases/compile_errors/invalid_optional_type_in_extern_struct.zig created+11
......@@ -0,0 +1,11 @@
1const stroo = extern struct {
2 moo: ?[*c]u8,
3};
4export fn testf(fluff: *stroo) void { _ = fluff; }
5
6// error
7// backend=stage2
8// target=native
9//
10// :4:8: error: extern structs cannot contain fields of type '?[*c]u8'
11// :4:8: note: only pointer like optionals are extern compatible
test/cases/compile_errors/non-const_variables_of_things_that_require_const_variables.zig+1
......@@ -40,5 +40,6 @@ const Opaque = opaque {};
4040// :14:8: note: to modify this variable at runtime, it must be given an explicit fixed-size number type
4141// :18:8: error: variable of type '@TypeOf(null)' must be const or comptime
4242// :22:19: error: values of type 'tmp.Opaque' must be comptime known, but operand value is runtime known
43// :22:19: note: opaque type 'tmp.Opaque' has undefined size
4344// :26:8: error: variable of type 'type' must be const or comptime
4445// :26:8: note: types are not available at runtime
test/cases/compile_errors/stage1/obj/exported_enum_without_explicit_integer_tag_type.zig deleted-15
......@@ -1,15 +0,0 @@
1const E = enum { one, two };
2comptime {
3 @export(E, .{ .name = "E" });
4}
5const e: E = .two;
6comptime {
7 @export(e, .{ .name = "e" });
8}
9
10// error
11// backend=stage1
12// target=native
13//
14// tmp.zig:3:13: error: exported enum without explicit integer tag type
15// tmp.zig:7:13: error: exported enum value without explicit integer tag type
test/cases/compile_errors/stage1/obj/extern_struct_with_extern-compatible_but_inferred_integer_tag_type.zig deleted-43
......@@ -1,43 +0,0 @@
1pub const E = enum {
2@"0",@"1",@"2",@"3",@"4",@"5",@"6",@"7",@"8",@"9",@"10",@"11",@"12",
3@"13",@"14",@"15",@"16",@"17",@"18",@"19",@"20",@"21",@"22",@"23",
4@"24",@"25",@"26",@"27",@"28",@"29",@"30",@"31",@"32",@"33",@"34",
5@"35",@"36",@"37",@"38",@"39",@"40",@"41",@"42",@"43",@"44",@"45",
6@"46",@"47",@"48",@"49",@"50",@"51",@"52",@"53",@"54",@"55",@"56",
7@"57",@"58",@"59",@"60",@"61",@"62",@"63",@"64",@"65",@"66",@"67",
8@"68",@"69",@"70",@"71",@"72",@"73",@"74",@"75",@"76",@"77",@"78",
9@"79",@"80",@"81",@"82",@"83",@"84",@"85",@"86",@"87",@"88",@"89",
10@"90",@"91",@"92",@"93",@"94",@"95",@"96",@"97",@"98",@"99",@"100",
11@"101",@"102",@"103",@"104",@"105",@"106",@"107",@"108",@"109",
12@"110",@"111",@"112",@"113",@"114",@"115",@"116",@"117",@"118",
13@"119",@"120",@"121",@"122",@"123",@"124",@"125",@"126",@"127",
14@"128",@"129",@"130",@"131",@"132",@"133",@"134",@"135",@"136",
15@"137",@"138",@"139",@"140",@"141",@"142",@"143",@"144",@"145",
16@"146",@"147",@"148",@"149",@"150",@"151",@"152",@"153",@"154",
17@"155",@"156",@"157",@"158",@"159",@"160",@"161",@"162",@"163",
18@"164",@"165",@"166",@"167",@"168",@"169",@"170",@"171",@"172",
19@"173",@"174",@"175",@"176",@"177",@"178",@"179",@"180",@"181",
20@"182",@"183",@"184",@"185",@"186",@"187",@"188",@"189",@"190",
21@"191",@"192",@"193",@"194",@"195",@"196",@"197",@"198",@"199",
22@"200",@"201",@"202",@"203",@"204",@"205",@"206",@"207",@"208",
23@"209",@"210",@"211",@"212",@"213",@"214",@"215",@"216",@"217",
24@"218",@"219",@"220",@"221",@"222",@"223",@"224",@"225",@"226",
25@"227",@"228",@"229",@"230",@"231",@"232",@"233",@"234",@"235",
26@"236",@"237",@"238",@"239",@"240",@"241",@"242",@"243",@"244",
27@"245",@"246",@"247",@"248",@"249",@"250",@"251",@"252",@"253",
28@"254",@"255"
29};
30pub const S = extern struct {
31 e: E,
32};
33export fn entry() void {
34 if (@typeInfo(E).Enum.tag_type != u8) @compileError("did not infer u8 tag type");
35 const s: S = undefined;
36 _ = s;
37}
38
39// error
40// backend=stage1
41// target=native
42//
43// tmp.zig:31:5: error: extern structs cannot contain fields of type 'E'
test/cases/compile_errors/stage1/obj/extern_struct_with_non-extern-compatible_integer_tag_type.zig deleted-14
......@@ -1,14 +0,0 @@
1pub const E = enum(u31) { A, B, C };
2pub const S = extern struct {
3 e: E,
4};
5export fn entry() void {
6 const s: S = undefined;
7 _ = s;
8}
9
10// error
11// backend=stage1
12// target=native
13//
14// tmp.zig:3:5: error: extern structs cannot contain fields of type 'E'
test/cases/compile_errors/stage1/obj/invalid_optional_type_in_extern_struct.zig deleted-10
......@@ -1,10 +0,0 @@
1const stroo = extern struct {
2 moo: ?[*c]u8,
3};
4export fn testf(fluff: *stroo) void { _ = fluff; }
5
6// error
7// backend=stage1
8// target=native
9//
10// tmp.zig:2:5: error: extern structs cannot contain fields of type '?[*c]u8'
test/cases/compile_errors/stage1/obj/optional_pointer_to_void_in_extern_struct.zig deleted-14
......@@ -1,14 +0,0 @@
1const Foo = extern struct {
2 x: ?*const void,
3};
4const Bar = extern struct {
5 foo: Foo,
6 y: i32,
7};
8export fn entry(bar: *Bar) void {_ = bar;}
9
10// error
11// backend=stage1
12// target=native
13//
14// tmp.zig:2:5: error: extern structs cannot contain fields of type '?*const void'
test/cases/compile_errors/stage1/optional_pointer_to_void_in_extern_struct.zig created+14
......@@ -0,0 +1,14 @@
1const Foo = extern struct {
2 x: ?*const void,
3};
4const Bar = extern struct {
5 foo: Foo,
6 y: i32,
7};
8export fn entry(bar: *Bar) void {_ = bar;}
9
10// error
11// backend=stage1
12// target=native
13//
14// tmp.zig:2:5: error: extern structs cannot contain fields of type '?*const void'