authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-02-27 00:05:08-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-02-27 00:07:11-05:00
log1195994880b6a83e61807381df2721ac5256e876
tree7ca30412d5c1ad7a3df15633ac3303b74b49eaf6
parent25761570f1bb4413020ebbfc959caa3429453517

fix inability to write to global in some cases

before, when we initialized a variable by copying the initialization value, it made the internal const value references point to a duplicate value, resulting in a phony duplicate global value being updated instead of the real on. now the behavior is as expected. thanks to hoppetosse for pointing out this bug on IRC.

7 files changed, 89 insertions(+), 89 deletions(-)

src/all_types.hpp+1-1
......@@ -1430,7 +1430,7 @@ enum VarLinkage {
14301430
14311431struct VariableTableEntry {
14321432 Buf name;
1433 ConstExprValue value;
1433 ConstExprValue *value;
14341434 LLVMValueRef value_ref;
14351435 bool src_is_const;
14361436 bool gen_is_const;
src/analyze.cpp+7-7
......@@ -2085,7 +2085,7 @@ VariableTableEntry *add_variable(CodeGen *g, AstNode *source_node, Scope *parent
20852085 assert(value);
20862086
20872087 VariableTableEntry *variable_entry = allocate<VariableTableEntry>(1);
2088 variable_entry->value = *value;
2088 variable_entry->value = value;
20892089 variable_entry->parent_scope = parent_scope;
20902090 variable_entry->shadowable = false;
20912091 variable_entry->mem_slot_index = SIZE_MAX;
......@@ -2101,21 +2101,21 @@ VariableTableEntry *add_variable(CodeGen *g, AstNode *source_node, Scope *parent
21012101 ErrorMsg *msg = add_node_error(g, source_node,
21022102 buf_sprintf("redeclaration of variable '%s'", buf_ptr(name)));
21032103 add_error_note(g, msg, existing_var->decl_node, buf_sprintf("previous declaration is here"));
2104 variable_entry->value.type = g->builtin_types.entry_invalid;
2104 variable_entry->value->type = g->builtin_types.entry_invalid;
21052105 } else {
21062106 auto primitive_table_entry = g->primitive_type_table.maybe_get(name);
21072107 if (primitive_table_entry) {
21082108 TypeTableEntry *type = primitive_table_entry->value;
21092109 add_node_error(g, source_node,
21102110 buf_sprintf("variable shadows type '%s'", buf_ptr(&type->name)));
2111 variable_entry->value.type = g->builtin_types.entry_invalid;
2111 variable_entry->value->type = g->builtin_types.entry_invalid;
21122112 } else {
21132113 Tld *tld = find_decl(g, parent_scope, name);
21142114 if (tld && tld->id != TldIdVar) {
21152115 ErrorMsg *msg = add_node_error(g, source_node,
21162116 buf_sprintf("redefinition of '%s'", buf_ptr(name)));
21172117 add_error_note(g, msg, tld->source_node, buf_sprintf("previous definition is here"));
2118 variable_entry->value.type = g->builtin_types.entry_invalid;
2118 variable_entry->value->type = g->builtin_types.entry_invalid;
21192119 }
21202120 }
21212121 }
......@@ -3181,7 +3181,7 @@ uint32_t fn_eval_hash(Scope* scope) {
31813181 while (scope) {
31823182 if (scope->id == ScopeIdVarDecl) {
31833183 ScopeVarDecl *var_scope = (ScopeVarDecl *)scope;
3184 result += hash_const_val(&var_scope->var->value);
3184 result += hash_const_val(var_scope->var->value);
31853185 } else if (scope->id == ScopeIdFnDef) {
31863186 ScopeFnDef *fn_scope = (ScopeFnDef *)scope;
31873187 result += hash_ptr(fn_scope->fn_entry);
......@@ -3203,9 +3203,9 @@ bool fn_eval_eql(Scope *a, Scope *b) {
32033203 if (a->id == ScopeIdVarDecl) {
32043204 ScopeVarDecl *a_var_scope = (ScopeVarDecl *)a;
32053205 ScopeVarDecl *b_var_scope = (ScopeVarDecl *)b;
3206 if (a_var_scope->var->value.type != b_var_scope->var->value.type)
3206 if (a_var_scope->var->value->type != b_var_scope->var->value->type)
32073207 return false;
3208 if (!const_values_equal(&a_var_scope->var->value, &b_var_scope->var->value))
3208 if (!const_values_equal(a_var_scope->var->value, b_var_scope->var->value))
32093209 return false;
32103210 } else if (a->id == ScopeIdFnDef) {
32113211 ScopeFnDef *a_fn_scope = (ScopeFnDef *)a;
src/ast_render.cpp+9-9
......@@ -964,26 +964,26 @@ static void ast_render_tld_var(AstRender *ar, Buf *name, TldVar *tld_var) {
964964 const char *extern_str = extern_string(var->linkage == VarLinkageExternal);
965965 fprintf(ar->f, "%s%s%s %s", visib_mod_str, extern_str, const_or_var, buf_ptr(name));
966966
967 if (var->value.type->id == TypeTableEntryIdNumLitFloat ||
968 var->value.type->id == TypeTableEntryIdNumLitInt ||
969 var->value.type->id == TypeTableEntryIdMetaType)
967 if (var->value->type->id == TypeTableEntryIdNumLitFloat ||
968 var->value->type->id == TypeTableEntryIdNumLitInt ||
969 var->value->type->id == TypeTableEntryIdMetaType)
970970 {
971971 // skip type
972972 } else {
973 fprintf(ar->f, ": %s", buf_ptr(&var->value.type->name));
973 fprintf(ar->f, ": %s", buf_ptr(&var->value->type->name));
974974 }
975975
976 if (var->value.special == ConstValSpecialRuntime) {
976 if (var->value->special == ConstValSpecialRuntime) {
977977 fprintf(ar->f, ";\n");
978978 return;
979979 }
980980
981981 fprintf(ar->f, " = ");
982982
983 if (var->value.special == ConstValSpecialStatic &&
984 var->value.type->id == TypeTableEntryIdMetaType)
983 if (var->value->special == ConstValSpecialStatic &&
984 var->value->type->id == TypeTableEntryIdMetaType)
985985 {
986 TypeTableEntry *type_entry = var->value.data.x_type;
986 TypeTableEntry *type_entry = var->value->data.x_type;
987987 if (type_entry->id == TypeTableEntryIdStruct) {
988988 const char *layout_str = layout_string(type_entry->data.structure.layout);
989989 fprintf(ar->f, "%sstruct {\n", layout_str);
......@@ -1022,7 +1022,7 @@ static void ast_render_tld_var(AstRender *ar, Buf *name, TldVar *tld_var) {
10221022 } else {
10231023 Buf buf = BUF_INIT;
10241024 buf_resize(&buf, 0);
1025 render_const_value(&buf, &var->value);
1025 render_const_value(&buf, var->value);
10261026 fprintf(ar->f, "%s", buf_ptr(&buf));
10271027 }
10281028
src/codegen.cpp+26-26
......@@ -1316,7 +1316,7 @@ static LLVMValueRef ir_render_decl_var(CodeGen *g, IrExecutable *executable,
13161316{
13171317 VariableTableEntry *var = decl_var_instruction->var;
13181318
1319 if (!type_has_bits(var->value.type))
1319 if (!type_has_bits(var->value->type))
13201320 return nullptr;
13211321
13221322 if (var->ref_count == 0 && g->is_release_build)
......@@ -1331,16 +1331,16 @@ static LLVMValueRef ir_render_decl_var(CodeGen *g, IrExecutable *executable,
13311331 have_init_expr = true;
13321332
13331333 if (have_init_expr) {
1334 assert(var->value.type == init_value->value.type);
1335 gen_assign_raw(g, var->value_ref, ir_llvm_value(g, init_value), var->value.type);
1334 assert(var->value->type == init_value->value.type);
1335 gen_assign_raw(g, var->value_ref, ir_llvm_value(g, init_value), var->value->type);
13361336 } else {
13371337 bool ignore_uninit = false;
13381338 // handle runtime stack allocation
13391339 bool want_safe = ir_want_debug_safety(g, &decl_var_instruction->base);
13401340 if (!ignore_uninit && want_safe) {
13411341 TypeTableEntry *usize = g->builtin_types.entry_usize;
1342 uint64_t size_bytes = LLVMStoreSizeOfType(g->target_data_ref, var->value.type->type_ref);
1343 uint64_t align_bytes = get_type_alignment(g, var->value.type);
1342 uint64_t size_bytes = LLVMStoreSizeOfType(g->target_data_ref, var->value->type->type_ref);
1343 uint64_t align_bytes = get_type_alignment(g, var->value->type);
13441344
13451345 // memset uninitialized memory to 0xa
13461346 LLVMTypeRef ptr_u8 = LLVMPointerType(LLVMInt8Type(), 0);
......@@ -1437,7 +1437,7 @@ static LLVMValueRef ir_render_store_ptr(CodeGen *g, IrExecutable *executable, Ir
14371437
14381438static LLVMValueRef ir_render_var_ptr(CodeGen *g, IrExecutable *executable, IrInstructionVarPtr *instruction) {
14391439 VariableTableEntry *var = instruction->var;
1440 if (type_has_bits(var->value.type)) {
1440 if (type_has_bits(var->value->type)) {
14411441 assert(var->value_ref);
14421442 return var->value_ref;
14431443 } else {
......@@ -3203,9 +3203,9 @@ static void do_code_gen(CodeGen *g) {
32033203 TldVar *tld_var = g->global_vars.at(i);
32043204 VariableTableEntry *var = tld_var->var;
32053205
3206 if (var->value.type->id == TypeTableEntryIdNumLitFloat) {
3206 if (var->value->type->id == TypeTableEntryIdNumLitFloat) {
32073207 // Generate debug info for it but that's it.
3208 ConstExprValue *const_val = &var->value;
3208 ConstExprValue *const_val = var->value;
32093209 assert(const_val->special != ConstValSpecialRuntime);
32103210 TypeTableEntry *var_type = g->builtin_types.entry_f64;
32113211 LLVMValueRef init_val = LLVMConstReal(var_type->type_ref, const_val->data.x_bignum.data.x_float);
......@@ -3213,9 +3213,9 @@ static void do_code_gen(CodeGen *g) {
32133213 continue;
32143214 }
32153215
3216 if (var->value.type->id == TypeTableEntryIdNumLitInt) {
3216 if (var->value->type->id == TypeTableEntryIdNumLitInt) {
32173217 // Generate debug info for it but that's it.
3218 ConstExprValue *const_val = &var->value;
3218 ConstExprValue *const_val = var->value;
32193219 assert(const_val->special != ConstValSpecialRuntime);
32203220 TypeTableEntry *var_type = const_val->data.x_bignum.is_negative ?
32213221 g->builtin_types.entry_isize : g->builtin_types.entry_usize;
......@@ -3225,22 +3225,22 @@ static void do_code_gen(CodeGen *g) {
32253225 continue;
32263226 }
32273227
3228 if (!type_has_bits(var->value.type))
3228 if (!type_has_bits(var->value->type))
32293229 continue;
32303230
32313231 assert(var->decl_node);
32323232
32333233 LLVMValueRef global_value;
32343234 if (var->linkage == VarLinkageExternal) {
3235 global_value = LLVMAddGlobal(g->module, var->value.type->type_ref, buf_ptr(&var->name));
3235 global_value = LLVMAddGlobal(g->module, var->value->type->type_ref, buf_ptr(&var->name));
32363236
32373237 // TODO debug info for the extern variable
32383238
32393239 LLVMSetLinkage(global_value, LLVMExternalLinkage);
32403240 } else {
3241 render_const_val(g, &var->value);
3242 render_const_val_global(g, &var->value, buf_ptr(&var->name));
3243 global_value = var->value.llvm_global;
3241 render_const_val(g, var->value);
3242 render_const_val_global(g, var->value, buf_ptr(&var->name));
3243 global_value = var->value->llvm_global;
32443244
32453245 if (var->linkage == VarLinkageExport) {
32463246 LLVMSetLinkage(global_value, LLVMExternalLinkage);
......@@ -3249,11 +3249,11 @@ static void do_code_gen(CodeGen *g) {
32493249 LLVMSetSection(global_value, buf_ptr(tld_var->section_name));
32503250 }
32513251 LLVMSetAlignment(global_value, tld_var->alignment ?
3252 tld_var->alignment : get_type_alignment(g, var->value.type));
3252 tld_var->alignment : get_type_alignment(g, var->value->type));
32533253
32543254 // TODO debug info for function pointers
3255 if (var->gen_is_const && var->value.type->id != TypeTableEntryIdFn) {
3256 gen_global_var(g, var, var->value.llvm_value, var->value.type);
3255 if (var->gen_is_const && var->value->type->id != TypeTableEntryIdFn) {
3256 gen_global_var(g, var, var->value->llvm_value, var->value->type);
32573257 }
32583258 }
32593259
......@@ -3432,30 +3432,30 @@ static void do_code_gen(CodeGen *g) {
34323432 for (size_t var_i = 0; var_i < fn_table_entry->variable_list.length; var_i += 1) {
34333433 VariableTableEntry *var = fn_table_entry->variable_list.at(var_i);
34343434
3435 if (!type_has_bits(var->value.type)) {
3435 if (!type_has_bits(var->value->type)) {
34363436 continue;
34373437 }
34383438 if (ir_get_var_is_comptime(var))
34393439 continue;
3440 if (type_requires_comptime(var->value.type))
3440 if (type_requires_comptime(var->value->type))
34413441 continue;
34423442
34433443 if (var->src_arg_index == SIZE_MAX) {
3444 var->value_ref = build_alloca(g, var->value.type, buf_ptr(&var->name));
3444 var->value_ref = build_alloca(g, var->value->type, buf_ptr(&var->name));
34453445
34463446 var->di_loc_var = ZigLLVMCreateAutoVariable(g->dbuilder, get_di_scope(g, var->parent_scope),
34473447 buf_ptr(&var->name), import->di_file, var->decl_node->line + 1,
3448 var->value.type->di_type, !g->strip_debug_symbols, 0);
3448 var->value->type->di_type, !g->strip_debug_symbols, 0);
34493449
34503450 } else {
34513451 assert(var->gen_arg_index != SIZE_MAX);
34523452 TypeTableEntry *gen_type;
3453 if (handle_is_ptr(var->value.type)) {
3453 if (handle_is_ptr(var->value->type)) {
34543454 gen_type = fn_table_entry->type_entry->data.fn.gen_param_info[var->src_arg_index].type;
34553455 var->value_ref = LLVMGetParam(fn, var->gen_arg_index);
34563456 } else {
3457 gen_type = var->value.type;
3458 var->value_ref = build_alloca(g, var->value.type, buf_ptr(&var->name));
3457 gen_type = var->value->type;
3458 var->value_ref = build_alloca(g, var->value->type, buf_ptr(&var->name));
34593459 }
34603460 if (var->decl_node) {
34613461 var->di_loc_var = ZigLLVMCreateParameterVariable(g->dbuilder, get_di_scope(g, var->parent_scope),
......@@ -3483,7 +3483,7 @@ static void do_code_gen(CodeGen *g) {
34833483 assert(variable);
34843484 assert(variable->value_ref);
34853485
3486 if (!handle_is_ptr(variable->value.type)) {
3486 if (!handle_is_ptr(variable->value->type)) {
34873487 clear_debug_source_node(g);
34883488 LLVMBuildStore(g->builder, LLVMGetParam(fn, variable->gen_arg_index), variable->value_ref);
34893489 }
src/ir.cpp+25-24
......@@ -3164,6 +3164,7 @@ static VariableTableEntry *create_local_var(CodeGen *codegen, AstNode *node, Sco
31643164 variable_entry->mem_slot_index = SIZE_MAX;
31653165 variable_entry->is_comptime = is_comptime;
31663166 variable_entry->src_arg_index = SIZE_MAX;
3167 variable_entry->value = allocate<ConstExprValue>(1);
31673168
31683169 if (name) {
31693170 buf_init_from_buf(&variable_entry->name, name);
......@@ -3173,21 +3174,21 @@ static VariableTableEntry *create_local_var(CodeGen *codegen, AstNode *node, Sco
31733174 ErrorMsg *msg = add_node_error(codegen, node,
31743175 buf_sprintf("redeclaration of variable '%s'", buf_ptr(name)));
31753176 add_error_note(codegen, msg, existing_var->decl_node, buf_sprintf("previous declaration is here"));
3176 variable_entry->value.type = codegen->builtin_types.entry_invalid;
3177 variable_entry->value->type = codegen->builtin_types.entry_invalid;
31773178 } else {
31783179 auto primitive_table_entry = codegen->primitive_type_table.maybe_get(name);
31793180 if (primitive_table_entry) {
31803181 TypeTableEntry *type = primitive_table_entry->value;
31813182 add_node_error(codegen, node,
31823183 buf_sprintf("variable shadows type '%s'", buf_ptr(&type->name)));
3183 variable_entry->value.type = codegen->builtin_types.entry_invalid;
3184 variable_entry->value->type = codegen->builtin_types.entry_invalid;
31843185 } else {
31853186 Tld *tld = find_decl(codegen, parent_scope, name);
31863187 if (tld && tld->id != TldIdVar) {
31873188 ErrorMsg *msg = add_node_error(codegen, node,
31883189 buf_sprintf("redefinition of '%s'", buf_ptr(name)));
31893190 add_error_note(codegen, msg, tld->source_node, buf_sprintf("previous definition is here"));
3190 variable_entry->value.type = codegen->builtin_types.entry_invalid;
3191 variable_entry->value->type = codegen->builtin_types.entry_invalid;
31913192 }
31923193 }
31933194 }
......@@ -4516,7 +4517,7 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, Scope *scope, AstNode *nod
45164517 // is inside var->child_scope
45174518
45184519 if (!is_extern && !variable_declaration->expr) {
4519 var->value.type = irb->codegen->builtin_types.entry_invalid;
4520 var->value->type = irb->codegen->builtin_types.entry_invalid;
45204521 add_node_error(irb->codegen, node, buf_sprintf("variables must be initialized"));
45214522 return irb->codegen->invalid_instruction;
45224523 }
......@@ -5387,7 +5388,7 @@ static bool render_instance_name_recursive(Buf *name, Scope *outer_scope, Scope
53875388 ScopeVarDecl *var_scope = (ScopeVarDecl *)inner_scope;
53885389 if (need_comma)
53895390 buf_append_char(name, ',');
5390 render_const_value(name, &var_scope->var->value);
5391 render_const_value(name, var_scope->var->value);
53915392 return true;
53925393}
53935394
......@@ -7827,8 +7828,8 @@ static TypeTableEntry *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstruc
78277828
78287829 IrInstruction *init_value = decl_var_instruction->init_value->other;
78297830 if (type_is_invalid(init_value->value.type)) {
7830 var->value.type = ira->codegen->builtin_types.entry_invalid;
7831 return var->value.type;
7831 var->value->type = ira->codegen->builtin_types.entry_invalid;
7832 return var->value->type;
78327833 }
78337834
78347835 AstNodeVariableDeclaration *variable_declaration = &var->decl_node->data.variable_declaration;
......@@ -7844,8 +7845,8 @@ static TypeTableEntry *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstruc
78447845 TypeTableEntry *proposed_type = ir_resolve_type(ira, var_type);
78457846 explicit_type = validate_var_type(ira->codegen, var_type->source_node, proposed_type);
78467847 if (type_is_invalid(explicit_type)) {
7847 var->value.type = ira->codegen->builtin_types.entry_invalid;
7848 return var->value.type;
7848 var->value->type = ira->codegen->builtin_types.entry_invalid;
7849 return var->value->type;
78497850 }
78507851 }
78517852
......@@ -7906,8 +7907,8 @@ static TypeTableEntry *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstruc
79067907 break;
79077908 }
79087909
7909 var->value.type = result_type;
7910 assert(var->value.type);
7910 var->value->type = result_type;
7911 assert(var->value->type);
79117912
79127913 if (type_is_invalid(result_type)) {
79137914 decl_var_instruction->base.other = &decl_var_instruction->base;
......@@ -7930,7 +7931,7 @@ static TypeTableEntry *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstruc
79307931 } else if (is_comptime) {
79317932 ir_add_error(ira, &decl_var_instruction->base,
79327933 buf_sprintf("cannot store runtime value in compile time variable"));
7933 var->value.type = ira->codegen->builtin_types.entry_invalid;
7934 var->value->type = ira->codegen->builtin_types.entry_invalid;
79347935 return ira->codegen->builtin_types.entry_invalid;
79357936 }
79367937
......@@ -8766,24 +8767,24 @@ static TypeTableEntry *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionP
87668767static TypeTableEntry *ir_analyze_var_ptr(IrAnalyze *ira, IrInstruction *instruction,
87678768 VariableTableEntry *var, bool is_const_ptr, bool is_volatile_ptr)
87688769{
8769 assert(var->value.type);
8770 if (type_is_invalid(var->value.type))
8771 return var->value.type;
8770 assert(var->value->type);
8771 if (type_is_invalid(var->value->type))
8772 return var->value->type;
87728773
87738774 bool comptime_var_mem = ir_get_var_is_comptime(var);
87748775
87758776 ConstExprValue *mem_slot = nullptr;
87768777 FnTableEntry *fn_entry = scope_fn_entry(var->parent_scope);
8777 if (var->value.special == ConstValSpecialStatic) {
8778 mem_slot = &var->value;
8778 if (var->value->special == ConstValSpecialStatic) {
8779 mem_slot = var->value;
87798780 } else if (fn_entry) {
87808781 // TODO once the analyze code is fully ported over to IR we won't need this SIZE_MAX thing.
87818782 if (var->mem_slot_index != SIZE_MAX && (comptime_var_mem || var->gen_is_const))
87828783 mem_slot = &ira->exec_context.mem_slot_list[var->mem_slot_index];
87838784 }
87848785
8785 bool is_const = (var->value.type->id == TypeTableEntryIdMetaType) ? is_const_ptr : var->src_is_const;
8786 bool is_volatile = (var->value.type->id == TypeTableEntryIdMetaType) ? is_volatile_ptr : false;
8786 bool is_const = (var->value->type->id == TypeTableEntryIdMetaType) ? is_const_ptr : var->src_is_const;
8787 bool is_volatile = (var->value->type->id == TypeTableEntryIdMetaType) ? is_volatile_ptr : false;
87878788 if (mem_slot && mem_slot->special != ConstValSpecialRuntime) {
87888789 ConstPtrMut ptr_mut;
87898790 if (comptime_var_mem) {
......@@ -8794,11 +8795,11 @@ static TypeTableEntry *ir_analyze_var_ptr(IrAnalyze *ira, IrInstruction *instruc
87948795 assert(!comptime_var_mem);
87958796 ptr_mut = ConstPtrMutRuntimeVar;
87968797 }
8797 return ir_analyze_const_ptr(ira, instruction, mem_slot, var->value.type, ptr_mut, is_const, is_volatile);
8798 return ir_analyze_const_ptr(ira, instruction, mem_slot, var->value->type, ptr_mut, is_const, is_volatile);
87988799 } else {
87998800 ir_build_var_ptr_from(&ira->new_irb, instruction, var, is_const, is_volatile);
8800 type_ensure_zero_bits_known(ira->codegen, var->value.type);
8801 return get_pointer_to_type(ira->codegen, var->value.type, var->src_is_const);
8801 type_ensure_zero_bits_known(ira->codegen, var->value->type);
8802 return get_pointer_to_type(ira->codegen, var->value->type, var->src_is_const);
88028803 }
88038804}
88048805
......@@ -12520,8 +12521,8 @@ FnTableEntry *ir_create_inline_fn(CodeGen *codegen, Buf *fn_name, VariableTableE
1252012521 fn_entry->fndef_scope = create_fndef_scope(nullptr, parent_scope, fn_entry);
1252112522 fn_entry->child_scope = &fn_entry->fndef_scope->base;
1252212523
12523 assert(var->value.type->id == TypeTableEntryIdMaybe);
12524 TypeTableEntry *src_fn_type = var->value.type->data.maybe.child_type;
12524 assert(var->value->type->id == TypeTableEntryIdMaybe);
12525 TypeTableEntry *src_fn_type = var->value->type->data.maybe.child_type;
1252512526 assert(src_fn_type->id == TypeTableEntryIdFn);
1252612527
1252712528 FnTypeId new_fn_type = src_fn_type->data.fn.fn_type_id;
src/parseh.cpp+1-1
......@@ -1235,7 +1235,7 @@ static void process_symbol_macros(Context *c) {
12351235 // variable is non-null and calls it.
12361236 if (existing_tld->id == TldIdVar) {
12371237 TldVar *tld_var = (TldVar *)existing_tld;
1238 TypeTableEntry *var_type = tld_var->var->value.type;
1238 TypeTableEntry *var_type = tld_var->var->value->type;
12391239 if (var_type->id == TypeTableEntryIdMaybe && !tld_var->var->src_is_const) {
12401240 TypeTableEntry *child_type = var_type->data.maybe.child_type;
12411241 if (child_type->id == TypeTableEntryIdFn) {
test/cases/array.zig+20-21
......@@ -72,24 +72,23 @@ fn nestedArrays() {
7272}
7373
7474
75// TODO
76//var s_array: [8]Sub = undefined;
77//const Sub = struct {
78// b: u8,
79//};
80//const Str = struct {
81// a: []Sub,
82//};
83//fn setGlobalVarArrayViaSliceEmbeddedInStruct() {
84// @setFnTest(this);
85//
86// var s = Str { .a = s_array[0...]};
87//
88// s.a[0].b = 1;
89// s.a[1].b = 2;
90// s.a[2].b = 3;
91//
92// assert(s_array[0].b == 1);
93// assert(s_array[1].b == 2);
94// assert(s_array[2].b == 3);
95//}
75var s_array: [8]Sub = undefined;
76const Sub = struct {
77 b: u8,
78};
79const Str = struct {
80 a: []Sub,
81};
82fn setGlobalVarArrayViaSliceEmbeddedInStruct() {
83 @setFnTest(this);
84
85 var s = Str { .a = s_array[0...]};
86
87 s.a[0].b = 1;
88 s.a[1].b = 2;
89 s.a[2].b = 3;
90
91 assert(s_array[0].b == 1);
92 assert(s_array[1].b == 2);
93 assert(s_array[2].b == 3);
94}