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 {...@@ -1430,7 +1430,7 @@ enum VarLinkage {
14301430
1431struct VariableTableEntry {1431struct VariableTableEntry {
1432 Buf name;1432 Buf name;
1433 ConstExprValue value;1433 ConstExprValue *value;
1434 LLVMValueRef value_ref;1434 LLVMValueRef value_ref;
1435 bool src_is_const;1435 bool src_is_const;
1436 bool gen_is_const;1436 bool gen_is_const;
src/analyze.cpp+7-7
...@@ -2085,7 +2085,7 @@ VariableTableEntry *add_variable(CodeGen *g, AstNode *source_node, Scope *parent...@@ -2085,7 +2085,7 @@ VariableTableEntry *add_variable(CodeGen *g, AstNode *source_node, Scope *parent
2085 assert(value);2085 assert(value);
20862086
2087 VariableTableEntry *variable_entry = allocate<VariableTableEntry>(1);2087 VariableTableEntry *variable_entry = allocate<VariableTableEntry>(1);
2088 variable_entry->value = *value;2088 variable_entry->value = value;
2089 variable_entry->parent_scope = parent_scope;2089 variable_entry->parent_scope = parent_scope;
2090 variable_entry->shadowable = false;2090 variable_entry->shadowable = false;
2091 variable_entry->mem_slot_index = SIZE_MAX;2091 variable_entry->mem_slot_index = SIZE_MAX;
...@@ -2101,21 +2101,21 @@ VariableTableEntry *add_variable(CodeGen *g, AstNode *source_node, Scope *parent...@@ -2101,21 +2101,21 @@ VariableTableEntry *add_variable(CodeGen *g, AstNode *source_node, Scope *parent
2101 ErrorMsg *msg = add_node_error(g, source_node,2101 ErrorMsg *msg = add_node_error(g, source_node,
2102 buf_sprintf("redeclaration of variable '%s'", buf_ptr(name)));2102 buf_sprintf("redeclaration of variable '%s'", buf_ptr(name)));
2103 add_error_note(g, msg, existing_var->decl_node, buf_sprintf("previous declaration is here"));2103 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;
2105 } else {2105 } else {
2106 auto primitive_table_entry = g->primitive_type_table.maybe_get(name);2106 auto primitive_table_entry = g->primitive_type_table.maybe_get(name);
2107 if (primitive_table_entry) {2107 if (primitive_table_entry) {
2108 TypeTableEntry *type = primitive_table_entry->value;2108 TypeTableEntry *type = primitive_table_entry->value;
2109 add_node_error(g, source_node,2109 add_node_error(g, source_node,
2110 buf_sprintf("variable shadows type '%s'", buf_ptr(&type->name)));2110 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;
2112 } else {2112 } else {
2113 Tld *tld = find_decl(g, parent_scope, name);2113 Tld *tld = find_decl(g, parent_scope, name);
2114 if (tld && tld->id != TldIdVar) {2114 if (tld && tld->id != TldIdVar) {
2115 ErrorMsg *msg = add_node_error(g, source_node,2115 ErrorMsg *msg = add_node_error(g, source_node,
2116 buf_sprintf("redefinition of '%s'", buf_ptr(name)));2116 buf_sprintf("redefinition of '%s'", buf_ptr(name)));
2117 add_error_note(g, msg, tld->source_node, buf_sprintf("previous definition is here"));2117 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;
2119 }2119 }
2120 }2120 }
2121 }2121 }
...@@ -3181,7 +3181,7 @@ uint32_t fn_eval_hash(Scope* scope) {...@@ -3181,7 +3181,7 @@ uint32_t fn_eval_hash(Scope* scope) {
3181 while (scope) {3181 while (scope) {
3182 if (scope->id == ScopeIdVarDecl) {3182 if (scope->id == ScopeIdVarDecl) {
3183 ScopeVarDecl *var_scope = (ScopeVarDecl *)scope;3183 ScopeVarDecl *var_scope = (ScopeVarDecl *)scope;
3184 result += hash_const_val(&var_scope->var->value);3184 result += hash_const_val(var_scope->var->value);
3185 } else if (scope->id == ScopeIdFnDef) {3185 } else if (scope->id == ScopeIdFnDef) {
3186 ScopeFnDef *fn_scope = (ScopeFnDef *)scope;3186 ScopeFnDef *fn_scope = (ScopeFnDef *)scope;
3187 result += hash_ptr(fn_scope->fn_entry);3187 result += hash_ptr(fn_scope->fn_entry);
...@@ -3203,9 +3203,9 @@ bool fn_eval_eql(Scope *a, Scope *b) {...@@ -3203,9 +3203,9 @@ bool fn_eval_eql(Scope *a, Scope *b) {
3203 if (a->id == ScopeIdVarDecl) {3203 if (a->id == ScopeIdVarDecl) {
3204 ScopeVarDecl *a_var_scope = (ScopeVarDecl *)a;3204 ScopeVarDecl *a_var_scope = (ScopeVarDecl *)a;
3205 ScopeVarDecl *b_var_scope = (ScopeVarDecl *)b;3205 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)
3207 return false;3207 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))
3209 return false;3209 return false;
3210 } else if (a->id == ScopeIdFnDef) {3210 } else if (a->id == ScopeIdFnDef) {
3211 ScopeFnDef *a_fn_scope = (ScopeFnDef *)a;3211 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) {...@@ -964,26 +964,26 @@ static void ast_render_tld_var(AstRender *ar, Buf *name, TldVar *tld_var) {
964 const char *extern_str = extern_string(var->linkage == VarLinkageExternal);964 const char *extern_str = extern_string(var->linkage == VarLinkageExternal);
965 fprintf(ar->f, "%s%s%s %s", visib_mod_str, extern_str, const_or_var, buf_ptr(name));965 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 ||967 if (var->value->type->id == TypeTableEntryIdNumLitFloat ||
968 var->value.type->id == TypeTableEntryIdNumLitInt ||968 var->value->type->id == TypeTableEntryIdNumLitInt ||
969 var->value.type->id == TypeTableEntryIdMetaType)969 var->value->type->id == TypeTableEntryIdMetaType)
970 {970 {
971 // skip type971 // skip type
972 } else {972 } else {
973 fprintf(ar->f, ": %s", buf_ptr(&var->value.type->name));973 fprintf(ar->f, ": %s", buf_ptr(&var->value->type->name));
974 }974 }
975975
976 if (var->value.special == ConstValSpecialRuntime) {976 if (var->value->special == ConstValSpecialRuntime) {
977 fprintf(ar->f, ";\n");977 fprintf(ar->f, ";\n");
978 return;978 return;
979 }979 }
980980
981 fprintf(ar->f, " = ");981 fprintf(ar->f, " = ");
982982
983 if (var->value.special == ConstValSpecialStatic &&983 if (var->value->special == ConstValSpecialStatic &&
984 var->value.type->id == TypeTableEntryIdMetaType)984 var->value->type->id == TypeTableEntryIdMetaType)
985 {985 {
986 TypeTableEntry *type_entry = var->value.data.x_type;986 TypeTableEntry *type_entry = var->value->data.x_type;
987 if (type_entry->id == TypeTableEntryIdStruct) {987 if (type_entry->id == TypeTableEntryIdStruct) {
988 const char *layout_str = layout_string(type_entry->data.structure.layout);988 const char *layout_str = layout_string(type_entry->data.structure.layout);
989 fprintf(ar->f, "%sstruct {\n", layout_str);989 fprintf(ar->f, "%sstruct {\n", layout_str);
...@@ -1022,7 +1022,7 @@ static void ast_render_tld_var(AstRender *ar, Buf *name, TldVar *tld_var) {...@@ -1022,7 +1022,7 @@ static void ast_render_tld_var(AstRender *ar, Buf *name, TldVar *tld_var) {
1022 } else {1022 } else {
1023 Buf buf = BUF_INIT;1023 Buf buf = BUF_INIT;
1024 buf_resize(&buf, 0);1024 buf_resize(&buf, 0);
1025 render_const_value(&buf, &var->value);1025 render_const_value(&buf, var->value);
1026 fprintf(ar->f, "%s", buf_ptr(&buf));1026 fprintf(ar->f, "%s", buf_ptr(&buf));
1027 }1027 }
10281028
src/codegen.cpp+26-26
...@@ -1316,7 +1316,7 @@ static LLVMValueRef ir_render_decl_var(CodeGen *g, IrExecutable *executable,...@@ -1316,7 +1316,7 @@ static LLVMValueRef ir_render_decl_var(CodeGen *g, IrExecutable *executable,
1316{1316{
1317 VariableTableEntry *var = decl_var_instruction->var;1317 VariableTableEntry *var = decl_var_instruction->var;
13181318
1319 if (!type_has_bits(var->value.type))1319 if (!type_has_bits(var->value->type))
1320 return nullptr;1320 return nullptr;
13211321
1322 if (var->ref_count == 0 && g->is_release_build)1322 if (var->ref_count == 0 && g->is_release_build)
...@@ -1331,16 +1331,16 @@ static LLVMValueRef ir_render_decl_var(CodeGen *g, IrExecutable *executable,...@@ -1331,16 +1331,16 @@ static LLVMValueRef ir_render_decl_var(CodeGen *g, IrExecutable *executable,
1331 have_init_expr = true;1331 have_init_expr = true;
13321332
1333 if (have_init_expr) {1333 if (have_init_expr) {
1334 assert(var->value.type == init_value->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);1335 gen_assign_raw(g, var->value_ref, ir_llvm_value(g, init_value), var->value->type);
1336 } else {1336 } else {
1337 bool ignore_uninit = false;1337 bool ignore_uninit = false;
1338 // handle runtime stack allocation1338 // handle runtime stack allocation
1339 bool want_safe = ir_want_debug_safety(g, &decl_var_instruction->base);1339 bool want_safe = ir_want_debug_safety(g, &decl_var_instruction->base);
1340 if (!ignore_uninit && want_safe) {1340 if (!ignore_uninit && want_safe) {
1341 TypeTableEntry *usize = g->builtin_types.entry_usize;1341 TypeTableEntry *usize = g->builtin_types.entry_usize;
1342 uint64_t size_bytes = LLVMStoreSizeOfType(g->target_data_ref, var->value.type->type_ref);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);1343 uint64_t align_bytes = get_type_alignment(g, var->value->type);
13441344
1345 // memset uninitialized memory to 0xa1345 // memset uninitialized memory to 0xa
1346 LLVMTypeRef ptr_u8 = LLVMPointerType(LLVMInt8Type(), 0);1346 LLVMTypeRef ptr_u8 = LLVMPointerType(LLVMInt8Type(), 0);
...@@ -1437,7 +1437,7 @@ static LLVMValueRef ir_render_store_ptr(CodeGen *g, IrExecutable *executable, Ir...@@ -1437,7 +1437,7 @@ static LLVMValueRef ir_render_store_ptr(CodeGen *g, IrExecutable *executable, Ir
14371437
1438static LLVMValueRef ir_render_var_ptr(CodeGen *g, IrExecutable *executable, IrInstructionVarPtr *instruction) {1438static LLVMValueRef ir_render_var_ptr(CodeGen *g, IrExecutable *executable, IrInstructionVarPtr *instruction) {
1439 VariableTableEntry *var = instruction->var;1439 VariableTableEntry *var = instruction->var;
1440 if (type_has_bits(var->value.type)) {1440 if (type_has_bits(var->value->type)) {
1441 assert(var->value_ref);1441 assert(var->value_ref);
1442 return var->value_ref;1442 return var->value_ref;
1443 } else {1443 } else {
...@@ -3203,9 +3203,9 @@ static void do_code_gen(CodeGen *g) {...@@ -3203,9 +3203,9 @@ static void do_code_gen(CodeGen *g) {
3203 TldVar *tld_var = g->global_vars.at(i);3203 TldVar *tld_var = g->global_vars.at(i);
3204 VariableTableEntry *var = tld_var->var;3204 VariableTableEntry *var = tld_var->var;
32053205
3206 if (var->value.type->id == TypeTableEntryIdNumLitFloat) {3206 if (var->value->type->id == TypeTableEntryIdNumLitFloat) {
3207 // Generate debug info for it but that's it.3207 // Generate debug info for it but that's it.
3208 ConstExprValue *const_val = &var->value;3208 ConstExprValue *const_val = var->value;
3209 assert(const_val->special != ConstValSpecialRuntime);3209 assert(const_val->special != ConstValSpecialRuntime);
3210 TypeTableEntry *var_type = g->builtin_types.entry_f64;3210 TypeTableEntry *var_type = g->builtin_types.entry_f64;
3211 LLVMValueRef init_val = LLVMConstReal(var_type->type_ref, const_val->data.x_bignum.data.x_float);3211 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) {...@@ -3213,9 +3213,9 @@ static void do_code_gen(CodeGen *g) {
3213 continue;3213 continue;
3214 }3214 }
32153215
3216 if (var->value.type->id == TypeTableEntryIdNumLitInt) {3216 if (var->value->type->id == TypeTableEntryIdNumLitInt) {
3217 // Generate debug info for it but that's it.3217 // Generate debug info for it but that's it.
3218 ConstExprValue *const_val = &var->value;3218 ConstExprValue *const_val = var->value;
3219 assert(const_val->special != ConstValSpecialRuntime);3219 assert(const_val->special != ConstValSpecialRuntime);
3220 TypeTableEntry *var_type = const_val->data.x_bignum.is_negative ?3220 TypeTableEntry *var_type = const_val->data.x_bignum.is_negative ?
3221 g->builtin_types.entry_isize : g->builtin_types.entry_usize;3221 g->builtin_types.entry_isize : g->builtin_types.entry_usize;
...@@ -3225,22 +3225,22 @@ static void do_code_gen(CodeGen *g) {...@@ -3225,22 +3225,22 @@ static void do_code_gen(CodeGen *g) {
3225 continue;3225 continue;
3226 }3226 }
32273227
3228 if (!type_has_bits(var->value.type))3228 if (!type_has_bits(var->value->type))
3229 continue;3229 continue;
32303230
3231 assert(var->decl_node);3231 assert(var->decl_node);
32323232
3233 LLVMValueRef global_value;3233 LLVMValueRef global_value;
3234 if (var->linkage == VarLinkageExternal) {3234 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
3237 // TODO debug info for the extern variable3237 // TODO debug info for the extern variable
32383238
3239 LLVMSetLinkage(global_value, LLVMExternalLinkage);3239 LLVMSetLinkage(global_value, LLVMExternalLinkage);
3240 } else {3240 } else {
3241 render_const_val(g, &var->value);3241 render_const_val(g, var->value);
3242 render_const_val_global(g, &var->value, buf_ptr(&var->name));3242 render_const_val_global(g, var->value, buf_ptr(&var->name));
3243 global_value = var->value.llvm_global;3243 global_value = var->value->llvm_global;
32443244
3245 if (var->linkage == VarLinkageExport) {3245 if (var->linkage == VarLinkageExport) {
3246 LLVMSetLinkage(global_value, LLVMExternalLinkage);3246 LLVMSetLinkage(global_value, LLVMExternalLinkage);
...@@ -3249,11 +3249,11 @@ static void do_code_gen(CodeGen *g) {...@@ -3249,11 +3249,11 @@ static void do_code_gen(CodeGen *g) {
3249 LLVMSetSection(global_value, buf_ptr(tld_var->section_name));3249 LLVMSetSection(global_value, buf_ptr(tld_var->section_name));
3250 }3250 }
3251 LLVMSetAlignment(global_value, tld_var->alignment ?3251 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
3254 // TODO debug info for function pointers3254 // TODO debug info for function pointers
3255 if (var->gen_is_const && var->value.type->id != TypeTableEntryIdFn) {3255 if (var->gen_is_const && var->value->type->id != TypeTableEntryIdFn) {
3256 gen_global_var(g, var, var->value.llvm_value, var->value.type);3256 gen_global_var(g, var, var->value->llvm_value, var->value->type);
3257 }3257 }
3258 }3258 }
32593259
...@@ -3432,30 +3432,30 @@ static void do_code_gen(CodeGen *g) {...@@ -3432,30 +3432,30 @@ static void do_code_gen(CodeGen *g) {
3432 for (size_t var_i = 0; var_i < fn_table_entry->variable_list.length; var_i += 1) {3432 for (size_t var_i = 0; var_i < fn_table_entry->variable_list.length; var_i += 1) {
3433 VariableTableEntry *var = fn_table_entry->variable_list.at(var_i);3433 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)) {
3436 continue;3436 continue;
3437 }3437 }
3438 if (ir_get_var_is_comptime(var))3438 if (ir_get_var_is_comptime(var))
3439 continue;3439 continue;
3440 if (type_requires_comptime(var->value.type))3440 if (type_requires_comptime(var->value->type))
3441 continue;3441 continue;
34423442
3443 if (var->src_arg_index == SIZE_MAX) {3443 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
3446 var->di_loc_var = ZigLLVMCreateAutoVariable(g->dbuilder, get_di_scope(g, var->parent_scope),3446 var->di_loc_var = ZigLLVMCreateAutoVariable(g->dbuilder, get_di_scope(g, var->parent_scope),
3447 buf_ptr(&var->name), import->di_file, var->decl_node->line + 1,3447 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
3450 } else {3450 } else {
3451 assert(var->gen_arg_index != SIZE_MAX);3451 assert(var->gen_arg_index != SIZE_MAX);
3452 TypeTableEntry *gen_type;3452 TypeTableEntry *gen_type;
3453 if (handle_is_ptr(var->value.type)) {3453 if (handle_is_ptr(var->value->type)) {
3454 gen_type = fn_table_entry->type_entry->data.fn.gen_param_info[var->src_arg_index].type;3454 gen_type = fn_table_entry->type_entry->data.fn.gen_param_info[var->src_arg_index].type;
3455 var->value_ref = LLVMGetParam(fn, var->gen_arg_index);3455 var->value_ref = LLVMGetParam(fn, var->gen_arg_index);
3456 } else {3456 } else {
3457 gen_type = var->value.type;3457 gen_type = var->value->type;
3458 var->value_ref = build_alloca(g, var->value.type, buf_ptr(&var->name));3458 var->value_ref = build_alloca(g, var->value->type, buf_ptr(&var->name));
3459 }3459 }
3460 if (var->decl_node) {3460 if (var->decl_node) {
3461 var->di_loc_var = ZigLLVMCreateParameterVariable(g->dbuilder, get_di_scope(g, var->parent_scope),3461 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) {...@@ -3483,7 +3483,7 @@ static void do_code_gen(CodeGen *g) {
3483 assert(variable);3483 assert(variable);
3484 assert(variable->value_ref);3484 assert(variable->value_ref);
34853485
3486 if (!handle_is_ptr(variable->value.type)) {3486 if (!handle_is_ptr(variable->value->type)) {
3487 clear_debug_source_node(g);3487 clear_debug_source_node(g);
3488 LLVMBuildStore(g->builder, LLVMGetParam(fn, variable->gen_arg_index), variable->value_ref);3488 LLVMBuildStore(g->builder, LLVMGetParam(fn, variable->gen_arg_index), variable->value_ref);
3489 }3489 }
src/ir.cpp+25-24
...@@ -3164,6 +3164,7 @@ static VariableTableEntry *create_local_var(CodeGen *codegen, AstNode *node, Sco...@@ -3164,6 +3164,7 @@ static VariableTableEntry *create_local_var(CodeGen *codegen, AstNode *node, Sco
3164 variable_entry->mem_slot_index = SIZE_MAX;3164 variable_entry->mem_slot_index = SIZE_MAX;
3165 variable_entry->is_comptime = is_comptime;3165 variable_entry->is_comptime = is_comptime;
3166 variable_entry->src_arg_index = SIZE_MAX;3166 variable_entry->src_arg_index = SIZE_MAX;
3167 variable_entry->value = allocate<ConstExprValue>(1);
31673168
3168 if (name) {3169 if (name) {
3169 buf_init_from_buf(&variable_entry->name, name);3170 buf_init_from_buf(&variable_entry->name, name);
...@@ -3173,21 +3174,21 @@ static VariableTableEntry *create_local_var(CodeGen *codegen, AstNode *node, Sco...@@ -3173,21 +3174,21 @@ static VariableTableEntry *create_local_var(CodeGen *codegen, AstNode *node, Sco
3173 ErrorMsg *msg = add_node_error(codegen, node,3174 ErrorMsg *msg = add_node_error(codegen, node,
3174 buf_sprintf("redeclaration of variable '%s'", buf_ptr(name)));3175 buf_sprintf("redeclaration of variable '%s'", buf_ptr(name)));
3175 add_error_note(codegen, msg, existing_var->decl_node, buf_sprintf("previous declaration is here"));3176 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;
3177 } else {3178 } else {
3178 auto primitive_table_entry = codegen->primitive_type_table.maybe_get(name);3179 auto primitive_table_entry = codegen->primitive_type_table.maybe_get(name);
3179 if (primitive_table_entry) {3180 if (primitive_table_entry) {
3180 TypeTableEntry *type = primitive_table_entry->value;3181 TypeTableEntry *type = primitive_table_entry->value;
3181 add_node_error(codegen, node,3182 add_node_error(codegen, node,
3182 buf_sprintf("variable shadows type '%s'", buf_ptr(&type->name)));3183 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;
3184 } else {3185 } else {
3185 Tld *tld = find_decl(codegen, parent_scope, name);3186 Tld *tld = find_decl(codegen, parent_scope, name);
3186 if (tld && tld->id != TldIdVar) {3187 if (tld && tld->id != TldIdVar) {
3187 ErrorMsg *msg = add_node_error(codegen, node,3188 ErrorMsg *msg = add_node_error(codegen, node,
3188 buf_sprintf("redefinition of '%s'", buf_ptr(name)));3189 buf_sprintf("redefinition of '%s'", buf_ptr(name)));
3189 add_error_note(codegen, msg, tld->source_node, buf_sprintf("previous definition is here"));3190 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;
3191 }3192 }
3192 }3193 }
3193 }3194 }
...@@ -4516,7 +4517,7 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, Scope *scope, AstNode *nod...@@ -4516,7 +4517,7 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, Scope *scope, AstNode *nod
4516 // is inside var->child_scope4517 // is inside var->child_scope
45174518
4518 if (!is_extern && !variable_declaration->expr) {4519 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;
4520 add_node_error(irb->codegen, node, buf_sprintf("variables must be initialized"));4521 add_node_error(irb->codegen, node, buf_sprintf("variables must be initialized"));
4521 return irb->codegen->invalid_instruction;4522 return irb->codegen->invalid_instruction;
4522 }4523 }
...@@ -5387,7 +5388,7 @@ static bool render_instance_name_recursive(Buf *name, Scope *outer_scope, Scope...@@ -5387,7 +5388,7 @@ static bool render_instance_name_recursive(Buf *name, Scope *outer_scope, Scope
5387 ScopeVarDecl *var_scope = (ScopeVarDecl *)inner_scope;5388 ScopeVarDecl *var_scope = (ScopeVarDecl *)inner_scope;
5388 if (need_comma)5389 if (need_comma)
5389 buf_append_char(name, ',');5390 buf_append_char(name, ',');
5390 render_const_value(name, &var_scope->var->value);5391 render_const_value(name, var_scope->var->value);
5391 return true;5392 return true;
5392}5393}
53935394
...@@ -7827,8 +7828,8 @@ static TypeTableEntry *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstruc...@@ -7827,8 +7828,8 @@ static TypeTableEntry *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstruc
78277828
7828 IrInstruction *init_value = decl_var_instruction->init_value->other;7829 IrInstruction *init_value = decl_var_instruction->init_value->other;
7829 if (type_is_invalid(init_value->value.type)) {7830 if (type_is_invalid(init_value->value.type)) {
7830 var->value.type = ira->codegen->builtin_types.entry_invalid;7831 var->value->type = ira->codegen->builtin_types.entry_invalid;
7831 return var->value.type;7832 return var->value->type;
7832 }7833 }
78337834
7834 AstNodeVariableDeclaration *variable_declaration = &var->decl_node->data.variable_declaration;7835 AstNodeVariableDeclaration *variable_declaration = &var->decl_node->data.variable_declaration;
...@@ -7844,8 +7845,8 @@ static TypeTableEntry *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstruc...@@ -7844,8 +7845,8 @@ static TypeTableEntry *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstruc
7844 TypeTableEntry *proposed_type = ir_resolve_type(ira, var_type);7845 TypeTableEntry *proposed_type = ir_resolve_type(ira, var_type);
7845 explicit_type = validate_var_type(ira->codegen, var_type->source_node, proposed_type);7846 explicit_type = validate_var_type(ira->codegen, var_type->source_node, proposed_type);
7846 if (type_is_invalid(explicit_type)) {7847 if (type_is_invalid(explicit_type)) {
7847 var->value.type = ira->codegen->builtin_types.entry_invalid;7848 var->value->type = ira->codegen->builtin_types.entry_invalid;
7848 return var->value.type;7849 return var->value->type;
7849 }7850 }
7850 }7851 }
78517852
...@@ -7906,8 +7907,8 @@ static TypeTableEntry *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstruc...@@ -7906,8 +7907,8 @@ static TypeTableEntry *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstruc
7906 break;7907 break;
7907 }7908 }
79087909
7909 var->value.type = result_type;7910 var->value->type = result_type;
7910 assert(var->value.type);7911 assert(var->value->type);
79117912
7912 if (type_is_invalid(result_type)) {7913 if (type_is_invalid(result_type)) {
7913 decl_var_instruction->base.other = &decl_var_instruction->base;7914 decl_var_instruction->base.other = &decl_var_instruction->base;
...@@ -7930,7 +7931,7 @@ static TypeTableEntry *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstruc...@@ -7930,7 +7931,7 @@ static TypeTableEntry *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstruc
7930 } else if (is_comptime) {7931 } else if (is_comptime) {
7931 ir_add_error(ira, &decl_var_instruction->base,7932 ir_add_error(ira, &decl_var_instruction->base,
7932 buf_sprintf("cannot store runtime value in compile time variable"));7933 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;
7934 return ira->codegen->builtin_types.entry_invalid;7935 return ira->codegen->builtin_types.entry_invalid;
7935 }7936 }
79367937
...@@ -8766,24 +8767,24 @@ static TypeTableEntry *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionP...@@ -8766,24 +8767,24 @@ static TypeTableEntry *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionP
8766static TypeTableEntry *ir_analyze_var_ptr(IrAnalyze *ira, IrInstruction *instruction,8767static TypeTableEntry *ir_analyze_var_ptr(IrAnalyze *ira, IrInstruction *instruction,
8767 VariableTableEntry *var, bool is_const_ptr, bool is_volatile_ptr)8768 VariableTableEntry *var, bool is_const_ptr, bool is_volatile_ptr)
8768{8769{
8769 assert(var->value.type);8770 assert(var->value->type);
8770 if (type_is_invalid(var->value.type))8771 if (type_is_invalid(var->value->type))
8771 return var->value.type;8772 return var->value->type;
87728773
8773 bool comptime_var_mem = ir_get_var_is_comptime(var);8774 bool comptime_var_mem = ir_get_var_is_comptime(var);
87748775
8775 ConstExprValue *mem_slot = nullptr;8776 ConstExprValue *mem_slot = nullptr;
8776 FnTableEntry *fn_entry = scope_fn_entry(var->parent_scope);8777 FnTableEntry *fn_entry = scope_fn_entry(var->parent_scope);
8777 if (var->value.special == ConstValSpecialStatic) {8778 if (var->value->special == ConstValSpecialStatic) {
8778 mem_slot = &var->value;8779 mem_slot = var->value;
8779 } else if (fn_entry) {8780 } else if (fn_entry) {
8780 // TODO once the analyze code is fully ported over to IR we won't need this SIZE_MAX thing.8781 // TODO once the analyze code is fully ported over to IR we won't need this SIZE_MAX thing.
8781 if (var->mem_slot_index != SIZE_MAX && (comptime_var_mem || var->gen_is_const))8782 if (var->mem_slot_index != SIZE_MAX && (comptime_var_mem || var->gen_is_const))
8782 mem_slot = &ira->exec_context.mem_slot_list[var->mem_slot_index];8783 mem_slot = &ira->exec_context.mem_slot_list[var->mem_slot_index];
8783 }8784 }
87848785
8785 bool is_const = (var->value.type->id == TypeTableEntryIdMetaType) ? is_const_ptr : var->src_is_const;8786 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;8787 bool is_volatile = (var->value->type->id == TypeTableEntryIdMetaType) ? is_volatile_ptr : false;
8787 if (mem_slot && mem_slot->special != ConstValSpecialRuntime) {8788 if (mem_slot && mem_slot->special != ConstValSpecialRuntime) {
8788 ConstPtrMut ptr_mut;8789 ConstPtrMut ptr_mut;
8789 if (comptime_var_mem) {8790 if (comptime_var_mem) {
...@@ -8794,11 +8795,11 @@ static TypeTableEntry *ir_analyze_var_ptr(IrAnalyze *ira, IrInstruction *instruc...@@ -8794,11 +8795,11 @@ static TypeTableEntry *ir_analyze_var_ptr(IrAnalyze *ira, IrInstruction *instruc
8794 assert(!comptime_var_mem);8795 assert(!comptime_var_mem);
8795 ptr_mut = ConstPtrMutRuntimeVar;8796 ptr_mut = ConstPtrMutRuntimeVar;
8796 }8797 }
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);
8798 } else {8799 } else {
8799 ir_build_var_ptr_from(&ira->new_irb, instruction, var, is_const, is_volatile);8800 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 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);8802 return get_pointer_to_type(ira->codegen, var->value->type, var->src_is_const);
8802 }8803 }
8803}8804}
88048805
...@@ -12520,8 +12521,8 @@ FnTableEntry *ir_create_inline_fn(CodeGen *codegen, Buf *fn_name, VariableTableE...@@ -12520,8 +12521,8 @@ FnTableEntry *ir_create_inline_fn(CodeGen *codegen, Buf *fn_name, VariableTableE
12520 fn_entry->fndef_scope = create_fndef_scope(nullptr, parent_scope, fn_entry);12521 fn_entry->fndef_scope = create_fndef_scope(nullptr, parent_scope, fn_entry);
12521 fn_entry->child_scope = &fn_entry->fndef_scope->base;12522 fn_entry->child_scope = &fn_entry->fndef_scope->base;
1252212523
12523 assert(var->value.type->id == TypeTableEntryIdMaybe);12524 assert(var->value->type->id == TypeTableEntryIdMaybe);
12524 TypeTableEntry *src_fn_type = var->value.type->data.maybe.child_type;12525 TypeTableEntry *src_fn_type = var->value->type->data.maybe.child_type;
12525 assert(src_fn_type->id == TypeTableEntryIdFn);12526 assert(src_fn_type->id == TypeTableEntryIdFn);
1252612527
12527 FnTypeId new_fn_type = src_fn_type->data.fn.fn_type_id;12528 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) {...@@ -1235,7 +1235,7 @@ static void process_symbol_macros(Context *c) {
1235 // variable is non-null and calls it.1235 // variable is non-null and calls it.
1236 if (existing_tld->id == TldIdVar) {1236 if (existing_tld->id == TldIdVar) {
1237 TldVar *tld_var = (TldVar *)existing_tld;1237 TldVar *tld_var = (TldVar *)existing_tld;
1238 TypeTableEntry *var_type = tld_var->var->value.type;1238 TypeTableEntry *var_type = tld_var->var->value->type;
1239 if (var_type->id == TypeTableEntryIdMaybe && !tld_var->var->src_is_const) {1239 if (var_type->id == TypeTableEntryIdMaybe && !tld_var->var->src_is_const) {
1240 TypeTableEntry *child_type = var_type->data.maybe.child_type;1240 TypeTableEntry *child_type = var_type->data.maybe.child_type;
1241 if (child_type->id == TypeTableEntryIdFn) {1241 if (child_type->id == TypeTableEntryIdFn) {
test/cases/array.zig+20-21
...@@ -72,24 +72,23 @@ fn nestedArrays() {...@@ -72,24 +72,23 @@ fn nestedArrays() {
72}72}
7373
7474
75// TODO75var s_array: [8]Sub = undefined;
76//var s_array: [8]Sub = undefined;76const Sub = struct {
77//const Sub = struct {77 b: u8,
78// b: u8,78};
79//};79const Str = struct {
80//const Str = struct {80 a: []Sub,
81// a: []Sub,81};
82//};82fn setGlobalVarArrayViaSliceEmbeddedInStruct() {
83//fn setGlobalVarArrayViaSliceEmbeddedInStruct() {83 @setFnTest(this);
84// @setFnTest(this);84
85//85 var s = Str { .a = s_array[0...]};
86// var s = Str { .a = s_array[0...]};86
87//87 s.a[0].b = 1;
88// s.a[0].b = 1;88 s.a[1].b = 2;
89// s.a[1].b = 2;89 s.a[2].b = 3;
90// s.a[2].b = 3;90
91//91 assert(s_array[0].b == 1);
92// assert(s_array[0].b == 1);92 assert(s_array[1].b == 2);
93// assert(s_array[1].b == 2);93 assert(s_array[2].b == 3);
94// assert(s_array[2].b == 3);94}
95//}