authorgravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2020-12-19 22:27:24+01:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-12-19 19:45:48-05:00
log84549b42678fa1f2755b2ec7bf4f4936d8f513af
tree6d1b3222ce827cc7e166f6cc15b6d81d4421b8c8
parentdd7b816d98840f26988c993eda9be21fa9b0ab50

stage1: Fix for generic fn monomorphization

Don't use the instantiation argument types to build the function parameter array. f416535768fc30195cad6cd481f73fd1e80082aa worked around the problem, this commit solves it.

3 files changed, 27 insertions(+), 5 deletions(-)

lib/std/crypto/tlcsprng.zig+1-3
...@@ -117,9 +117,7 @@ fn setupPthreadAtforkAndFill(buffer: []u8) void {...@@ -117,9 +117,7 @@ fn setupPthreadAtforkAndFill(buffer: []u8) void {
117}117}
118118
119fn childAtForkHandler() callconv(.C) void {119fn childAtForkHandler() callconv(.C) void {
120 // TODO this is a workaround for https://github.com/ziglang/zig/issues/7495120 const wipe_slice = @ptrCast([*]u8, &wipe_me)[0..@sizeOf(@TypeOf(wipe_me))];
121 var wipe_slice: []u8 = undefined;
122 wipe_slice = @ptrCast([*]u8, &wipe_me)[0..@sizeOf(@TypeOf(wipe_me))];
123 std.crypto.utils.secureZero(u8, wipe_slice);121 std.crypto.utils.secureZero(u8, wipe_slice);
124}122}
125123
src/stage1/ir.cpp+7-1
...@@ -20226,9 +20226,12 @@ static bool ir_analyze_fn_call_generic_arg(IrAnalyze *ira, AstNode *fn_proto_nod...@@ -20226,9 +20226,12 @@ static bool ir_analyze_fn_call_generic_arg(IrAnalyze *ira, AstNode *fn_proto_nod
20226 bool is_var_args = param_decl_node->data.param_decl.is_var_args;20226 bool is_var_args = param_decl_node->data.param_decl.is_var_args;
20227 bool arg_part_of_generic_id = false;20227 bool arg_part_of_generic_id = false;
20228 IrInstGen *casted_arg;20228 IrInstGen *casted_arg;
20229
20230 ZigType *param_info_type = nullptr;
20229 if (is_var_args) {20231 if (is_var_args) {
20230 arg_part_of_generic_id = true;20232 arg_part_of_generic_id = true;
20231 casted_arg = arg;20233 casted_arg = arg;
20234 param_info_type = arg->value->type;
20232 } else {20235 } else {
20233 if (param_decl_node->data.param_decl.anytype_token == nullptr) {20236 if (param_decl_node->data.param_decl.anytype_token == nullptr) {
20234 AstNode *param_type_node = param_decl_node->data.param_decl.type;20237 AstNode *param_type_node = param_decl_node->data.param_decl.type;
...@@ -20239,9 +20242,12 @@ static bool ir_analyze_fn_call_generic_arg(IrAnalyze *ira, AstNode *fn_proto_nod...@@ -20239,9 +20242,12 @@ static bool ir_analyze_fn_call_generic_arg(IrAnalyze *ira, AstNode *fn_proto_nod
20239 casted_arg = ir_implicit_cast2(ira, arg_src, arg, param_type);20242 casted_arg = ir_implicit_cast2(ira, arg_src, arg, param_type);
20240 if (type_is_invalid(casted_arg->value->type))20243 if (type_is_invalid(casted_arg->value->type))
20241 return false;20244 return false;
20245
20246 param_info_type = param_type;
20242 } else {20247 } else {
20243 arg_part_of_generic_id = true;20248 arg_part_of_generic_id = true;
20244 casted_arg = arg;20249 casted_arg = arg;
20250 param_info_type = arg->value->type;
20245 }20251 }
20246 }20252 }
2024720253
...@@ -20298,7 +20304,7 @@ static bool ir_analyze_fn_call_generic_arg(IrAnalyze *ira, AstNode *fn_proto_nod...@@ -20298,7 +20304,7 @@ static bool ir_analyze_fn_call_generic_arg(IrAnalyze *ira, AstNode *fn_proto_nod
20298 if (!comptime_arg) {20304 if (!comptime_arg) {
20299 casted_args[fn_type_id->param_count] = casted_arg;20305 casted_args[fn_type_id->param_count] = casted_arg;
20300 FnTypeParamInfo *param_info = &fn_type_id->param_info[fn_type_id->param_count];20306 FnTypeParamInfo *param_info = &fn_type_id->param_info[fn_type_id->param_count];
20301 param_info->type = casted_arg->value->type;20307 param_info->type = param_info_type;
20302 param_info->is_noalias = param_decl_node->data.param_decl.is_noalias;20308 param_info->is_noalias = param_decl_node->data.param_decl.is_noalias;
20303 impl_fn->param_source_nodes[fn_type_id->param_count] = param_decl_node;20309 impl_fn->param_source_nodes[fn_type_id->param_count] = param_decl_node;
20304 fn_type_id->param_count += 1;20310 fn_type_id->param_count += 1;
test/stage1/behavior/generics.zig+19-1
...@@ -1,4 +1,7 @@...@@ -1,4 +1,7 @@
1const expect = @import("std").testing.expect;1const std = @import("std");
2const testing = std.testing;
3const expect = testing.expect;
4const expectEqual = testing.expectEqual;
25
3test "simple generic fn" {6test "simple generic fn" {
4 expect(max(i32, 3, -1) == 3);7 expect(max(i32, 3, -1) == 3);
...@@ -149,3 +152,18 @@ test "array of generic fns" {...@@ -149,3 +152,18 @@ test "array of generic fns" {
149 expect(foos[0](true));152 expect(foos[0](true));
150 expect(!foos[1](true));153 expect(!foos[1](true));
151}154}
155
156test "generic fn keeps non-generic parameter types" {
157 const A = 128;
158
159 const S = struct {
160 fn f(comptime T: type, s: []T) void {
161 expect(A != @typeInfo(@TypeOf(s)).Pointer.alignment);
162 }
163 };
164
165 // The compiler monomorphizes `S.f` for `T=u8` on its first use, check that
166 // `x` type not affect `s` parameter type.
167 var x: [16]u8 align(A) = undefined;
168 S.f(u8, &x);
169}