| author | |
| committer | |
| log | 1195994880b6a83e61807381df2721ac5256e876 |
| tree | 7ca30412d5c1ad7a3df15633ac3303b74b49eaf6 |
| parent | 25761570f1bb4413020ebbfc959caa3429453517 |
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 | 1430 | |
| 1431 | 1431 | struct VariableTableEntry { |
| 1432 | 1432 | Buf name; |
| 1433 | ConstExprValue value; | |
| 1433 | ConstExprValue *value; | |
| 1434 | 1434 | LLVMValueRef value_ref; |
| 1435 | 1435 | bool src_is_const; |
| 1436 | 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 | 2085 | assert(value); |
| 2086 | 2086 | |
| 2087 | 2087 | VariableTableEntry *variable_entry = allocate<VariableTableEntry>(1); |
| 2088 | variable_entry->value = *value; | |
| 2088 | variable_entry->value = value; | |
| 2089 | 2089 | variable_entry->parent_scope = parent_scope; |
| 2090 | 2090 | variable_entry->shadowable = false; |
| 2091 | 2091 | variable_entry->mem_slot_index = SIZE_MAX; |
| ... | ... | @@ -2101,21 +2101,21 @@ VariableTableEntry *add_variable(CodeGen *g, AstNode *source_node, Scope *parent |
| 2101 | 2101 | ErrorMsg *msg = add_node_error(g, source_node, |
| 2102 | 2102 | buf_sprintf("redeclaration of variable '%s'", buf_ptr(name))); |
| 2103 | 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 | 2105 | } else { |
| 2106 | 2106 | auto primitive_table_entry = g->primitive_type_table.maybe_get(name); |
| 2107 | 2107 | if (primitive_table_entry) { |
| 2108 | 2108 | TypeTableEntry *type = primitive_table_entry->value; |
| 2109 | 2109 | add_node_error(g, source_node, |
| 2110 | 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 | 2112 | } else { |
| 2113 | 2113 | Tld *tld = find_decl(g, parent_scope, name); |
| 2114 | 2114 | if (tld && tld->id != TldIdVar) { |
| 2115 | 2115 | ErrorMsg *msg = add_node_error(g, source_node, |
| 2116 | 2116 | buf_sprintf("redefinition of '%s'", buf_ptr(name))); |
| 2117 | 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 | 3181 | while (scope) { |
| 3182 | 3182 | if (scope->id == ScopeIdVarDecl) { |
| 3183 | 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 | 3185 | } else if (scope->id == ScopeIdFnDef) { |
| 3186 | 3186 | ScopeFnDef *fn_scope = (ScopeFnDef *)scope; |
| 3187 | 3187 | result += hash_ptr(fn_scope->fn_entry); |
| ... | ... | @@ -3203,9 +3203,9 @@ bool fn_eval_eql(Scope *a, Scope *b) { |
| 3203 | 3203 | if (a->id == ScopeIdVarDecl) { |
| 3204 | 3204 | ScopeVarDecl *a_var_scope = (ScopeVarDecl *)a; |
| 3205 | 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 | 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 | 3209 | return false; |
| 3210 | 3210 | } else if (a->id == ScopeIdFnDef) { |
| 3211 | 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 | 964 | const char *extern_str = extern_string(var->linkage == VarLinkageExternal); |
| 965 | 965 | fprintf(ar->f, "%s%s%s %s", visib_mod_str, extern_str, const_or_var, buf_ptr(name)); |
| 966 | 966 | |
| 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) | |
| 970 | 970 | { |
| 971 | 971 | // skip type |
| 972 | 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 | } |
| 975 | 975 | |
| 976 | if (var->value.special == ConstValSpecialRuntime) { | |
| 976 | if (var->value->special == ConstValSpecialRuntime) { | |
| 977 | 977 | fprintf(ar->f, ";\n"); |
| 978 | 978 | return; |
| 979 | 979 | } |
| 980 | 980 | |
| 981 | 981 | fprintf(ar->f, " = "); |
| 982 | 982 | |
| 983 | if (var->value.special == ConstValSpecialStatic && | |
| 984 | var->value.type->id == TypeTableEntryIdMetaType) | |
| 983 | if (var->value->special == ConstValSpecialStatic && | |
| 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 | 987 | if (type_entry->id == TypeTableEntryIdStruct) { |
| 988 | 988 | const char *layout_str = layout_string(type_entry->data.structure.layout); |
| 989 | 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 | 1022 | } else { |
| 1023 | 1023 | Buf buf = BUF_INIT; |
| 1024 | 1024 | buf_resize(&buf, 0); |
| 1025 | render_const_value(&buf, &var->value); | |
| 1025 | render_const_value(&buf, var->value); | |
| 1026 | 1026 | fprintf(ar->f, "%s", buf_ptr(&buf)); |
| 1027 | 1027 | } |
| 1028 | 1028 |
src/codegen.cpp+26-26| ... | ... | @@ -1316,7 +1316,7 @@ static LLVMValueRef ir_render_decl_var(CodeGen *g, IrExecutable *executable, |
| 1316 | 1316 | { |
| 1317 | 1317 | VariableTableEntry *var = decl_var_instruction->var; |
| 1318 | 1318 | |
| 1319 | if (!type_has_bits(var->value.type)) | |
| 1319 | if (!type_has_bits(var->value->type)) | |
| 1320 | 1320 | return nullptr; |
| 1321 | 1321 | |
| 1322 | 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 | 1331 | have_init_expr = true; |
| 1332 | 1332 | |
| 1333 | 1333 | 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); | |
| 1336 | 1336 | } else { |
| 1337 | 1337 | bool ignore_uninit = false; |
| 1338 | 1338 | // handle runtime stack allocation |
| 1339 | 1339 | bool want_safe = ir_want_debug_safety(g, &decl_var_instruction->base); |
| 1340 | 1340 | if (!ignore_uninit && want_safe) { |
| 1341 | 1341 | 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); | |
| 1344 | 1344 | |
| 1345 | 1345 | // memset uninitialized memory to 0xa |
| 1346 | 1346 | LLVMTypeRef ptr_u8 = LLVMPointerType(LLVMInt8Type(), 0); |
| ... | ... | @@ -1437,7 +1437,7 @@ static LLVMValueRef ir_render_store_ptr(CodeGen *g, IrExecutable *executable, Ir |
| 1437 | 1437 | |
| 1438 | 1438 | static LLVMValueRef ir_render_var_ptr(CodeGen *g, IrExecutable *executable, IrInstructionVarPtr *instruction) { |
| 1439 | 1439 | VariableTableEntry *var = instruction->var; |
| 1440 | if (type_has_bits(var->value.type)) { | |
| 1440 | if (type_has_bits(var->value->type)) { | |
| 1441 | 1441 | assert(var->value_ref); |
| 1442 | 1442 | return var->value_ref; |
| 1443 | 1443 | } else { |
| ... | ... | @@ -3203,9 +3203,9 @@ static void do_code_gen(CodeGen *g) { |
| 3203 | 3203 | TldVar *tld_var = g->global_vars.at(i); |
| 3204 | 3204 | VariableTableEntry *var = tld_var->var; |
| 3205 | 3205 | |
| 3206 | if (var->value.type->id == TypeTableEntryIdNumLitFloat) { | |
| 3206 | if (var->value->type->id == TypeTableEntryIdNumLitFloat) { | |
| 3207 | 3207 | // Generate debug info for it but that's it. |
| 3208 | ConstExprValue *const_val = &var->value; | |
| 3208 | ConstExprValue *const_val = var->value; | |
| 3209 | 3209 | assert(const_val->special != ConstValSpecialRuntime); |
| 3210 | 3210 | TypeTableEntry *var_type = g->builtin_types.entry_f64; |
| 3211 | 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 | 3213 | continue; |
| 3214 | 3214 | } |
| 3215 | 3215 | |
| 3216 | if (var->value.type->id == TypeTableEntryIdNumLitInt) { | |
| 3216 | if (var->value->type->id == TypeTableEntryIdNumLitInt) { | |
| 3217 | 3217 | // Generate debug info for it but that's it. |
| 3218 | ConstExprValue *const_val = &var->value; | |
| 3218 | ConstExprValue *const_val = var->value; | |
| 3219 | 3219 | assert(const_val->special != ConstValSpecialRuntime); |
| 3220 | 3220 | TypeTableEntry *var_type = const_val->data.x_bignum.is_negative ? |
| 3221 | 3221 | g->builtin_types.entry_isize : g->builtin_types.entry_usize; |
| ... | ... | @@ -3225,22 +3225,22 @@ static void do_code_gen(CodeGen *g) { |
| 3225 | 3225 | continue; |
| 3226 | 3226 | } |
| 3227 | 3227 | |
| 3228 | if (!type_has_bits(var->value.type)) | |
| 3228 | if (!type_has_bits(var->value->type)) | |
| 3229 | 3229 | continue; |
| 3230 | 3230 | |
| 3231 | 3231 | assert(var->decl_node); |
| 3232 | 3232 | |
| 3233 | 3233 | LLVMValueRef global_value; |
| 3234 | 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)); | |
| 3236 | 3236 | |
| 3237 | 3237 | // TODO debug info for the extern variable |
| 3238 | 3238 | |
| 3239 | 3239 | LLVMSetLinkage(global_value, LLVMExternalLinkage); |
| 3240 | 3240 | } 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; | |
| 3244 | 3244 | |
| 3245 | 3245 | if (var->linkage == VarLinkageExport) { |
| 3246 | 3246 | LLVMSetLinkage(global_value, LLVMExternalLinkage); |
| ... | ... | @@ -3249,11 +3249,11 @@ static void do_code_gen(CodeGen *g) { |
| 3249 | 3249 | LLVMSetSection(global_value, buf_ptr(tld_var->section_name)); |
| 3250 | 3250 | } |
| 3251 | 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)); | |
| 3253 | 3253 | |
| 3254 | 3254 | // 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); | |
| 3257 | 3257 | } |
| 3258 | 3258 | } |
| 3259 | 3259 | |
| ... | ... | @@ -3432,30 +3432,30 @@ static void do_code_gen(CodeGen *g) { |
| 3432 | 3432 | for (size_t var_i = 0; var_i < fn_table_entry->variable_list.length; var_i += 1) { |
| 3433 | 3433 | VariableTableEntry *var = fn_table_entry->variable_list.at(var_i); |
| 3434 | 3434 | |
| 3435 | if (!type_has_bits(var->value.type)) { | |
| 3435 | if (!type_has_bits(var->value->type)) { | |
| 3436 | 3436 | continue; |
| 3437 | 3437 | } |
| 3438 | 3438 | if (ir_get_var_is_comptime(var)) |
| 3439 | 3439 | continue; |
| 3440 | if (type_requires_comptime(var->value.type)) | |
| 3440 | if (type_requires_comptime(var->value->type)) | |
| 3441 | 3441 | continue; |
| 3442 | 3442 | |
| 3443 | 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)); | |
| 3445 | 3445 | |
| 3446 | 3446 | var->di_loc_var = ZigLLVMCreateAutoVariable(g->dbuilder, get_di_scope(g, var->parent_scope), |
| 3447 | 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); | |
| 3449 | 3449 | |
| 3450 | 3450 | } else { |
| 3451 | 3451 | assert(var->gen_arg_index != SIZE_MAX); |
| 3452 | 3452 | TypeTableEntry *gen_type; |
| 3453 | if (handle_is_ptr(var->value.type)) { | |
| 3453 | if (handle_is_ptr(var->value->type)) { | |
| 3454 | 3454 | gen_type = fn_table_entry->type_entry->data.fn.gen_param_info[var->src_arg_index].type; |
| 3455 | 3455 | var->value_ref = LLVMGetParam(fn, var->gen_arg_index); |
| 3456 | 3456 | } 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)); | |
| 3459 | 3459 | } |
| 3460 | 3460 | if (var->decl_node) { |
| 3461 | 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 | 3483 | assert(variable); |
| 3484 | 3484 | assert(variable->value_ref); |
| 3485 | 3485 | |
| 3486 | if (!handle_is_ptr(variable->value.type)) { | |
| 3486 | if (!handle_is_ptr(variable->value->type)) { | |
| 3487 | 3487 | clear_debug_source_node(g); |
| 3488 | 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 | 3164 | variable_entry->mem_slot_index = SIZE_MAX; |
| 3165 | 3165 | variable_entry->is_comptime = is_comptime; |
| 3166 | 3166 | variable_entry->src_arg_index = SIZE_MAX; |
| 3167 | variable_entry->value = allocate<ConstExprValue>(1); | |
| 3167 | 3168 | |
| 3168 | 3169 | if (name) { |
| 3169 | 3170 | buf_init_from_buf(&variable_entry->name, name); |
| ... | ... | @@ -3173,21 +3174,21 @@ static VariableTableEntry *create_local_var(CodeGen *codegen, AstNode *node, Sco |
| 3173 | 3174 | ErrorMsg *msg = add_node_error(codegen, node, |
| 3174 | 3175 | buf_sprintf("redeclaration of variable '%s'", buf_ptr(name))); |
| 3175 | 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 | 3178 | } else { |
| 3178 | 3179 | auto primitive_table_entry = codegen->primitive_type_table.maybe_get(name); |
| 3179 | 3180 | if (primitive_table_entry) { |
| 3180 | 3181 | TypeTableEntry *type = primitive_table_entry->value; |
| 3181 | 3182 | add_node_error(codegen, node, |
| 3182 | 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 | 3185 | } else { |
| 3185 | 3186 | Tld *tld = find_decl(codegen, parent_scope, name); |
| 3186 | 3187 | if (tld && tld->id != TldIdVar) { |
| 3187 | 3188 | ErrorMsg *msg = add_node_error(codegen, node, |
| 3188 | 3189 | buf_sprintf("redefinition of '%s'", buf_ptr(name))); |
| 3189 | 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 | 4517 | // is inside var->child_scope |
| 4517 | 4518 | |
| 4518 | 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 | 4521 | add_node_error(irb->codegen, node, buf_sprintf("variables must be initialized")); |
| 4521 | 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 | 5388 | ScopeVarDecl *var_scope = (ScopeVarDecl *)inner_scope; |
| 5388 | 5389 | if (need_comma) |
| 5389 | 5390 | buf_append_char(name, ','); |
| 5390 | render_const_value(name, &var_scope->var->value); | |
| 5391 | render_const_value(name, var_scope->var->value); | |
| 5391 | 5392 | return true; |
| 5392 | 5393 | } |
| 5393 | 5394 | |
| ... | ... | @@ -7827,8 +7828,8 @@ static TypeTableEntry *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstruc |
| 7827 | 7828 | |
| 7828 | 7829 | IrInstruction *init_value = decl_var_instruction->init_value->other; |
| 7829 | 7830 | 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; | |
| 7832 | 7833 | } |
| 7833 | 7834 | |
| 7834 | 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 | 7845 | TypeTableEntry *proposed_type = ir_resolve_type(ira, var_type); |
| 7845 | 7846 | explicit_type = validate_var_type(ira->codegen, var_type->source_node, proposed_type); |
| 7846 | 7847 | 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; | |
| 7849 | 7850 | } |
| 7850 | 7851 | } |
| 7851 | 7852 | |
| ... | ... | @@ -7906,8 +7907,8 @@ static TypeTableEntry *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstruc |
| 7906 | 7907 | break; |
| 7907 | 7908 | } |
| 7908 | 7909 | |
| 7909 | var->value.type = result_type; | |
| 7910 | assert(var->value.type); | |
| 7910 | var->value->type = result_type; | |
| 7911 | assert(var->value->type); | |
| 7911 | 7912 | |
| 7912 | 7913 | if (type_is_invalid(result_type)) { |
| 7913 | 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 | 7931 | } else if (is_comptime) { |
| 7931 | 7932 | ir_add_error(ira, &decl_var_instruction->base, |
| 7932 | 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 | 7935 | return ira->codegen->builtin_types.entry_invalid; |
| 7935 | 7936 | } |
| 7936 | 7937 | |
| ... | ... | @@ -8766,24 +8767,24 @@ static TypeTableEntry *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionP |
| 8766 | 8767 | static TypeTableEntry *ir_analyze_var_ptr(IrAnalyze *ira, IrInstruction *instruction, |
| 8767 | 8768 | VariableTableEntry *var, bool is_const_ptr, bool is_volatile_ptr) |
| 8768 | 8769 | { |
| 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; | |
| 8772 | 8773 | |
| 8773 | 8774 | bool comptime_var_mem = ir_get_var_is_comptime(var); |
| 8774 | 8775 | |
| 8775 | 8776 | ConstExprValue *mem_slot = nullptr; |
| 8776 | 8777 | 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; | |
| 8779 | 8780 | } else if (fn_entry) { |
| 8780 | 8781 | // TODO once the analyze code is fully ported over to IR we won't need this SIZE_MAX thing. |
| 8781 | 8782 | if (var->mem_slot_index != SIZE_MAX && (comptime_var_mem || var->gen_is_const)) |
| 8782 | 8783 | mem_slot = &ira->exec_context.mem_slot_list[var->mem_slot_index]; |
| 8783 | 8784 | } |
| 8784 | 8785 | |
| 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; | |
| 8787 | 8788 | if (mem_slot && mem_slot->special != ConstValSpecialRuntime) { |
| 8788 | 8789 | ConstPtrMut ptr_mut; |
| 8789 | 8790 | if (comptime_var_mem) { |
| ... | ... | @@ -8794,11 +8795,11 @@ static TypeTableEntry *ir_analyze_var_ptr(IrAnalyze *ira, IrInstruction *instruc |
| 8794 | 8795 | assert(!comptime_var_mem); |
| 8795 | 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 | 8799 | } else { |
| 8799 | 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 | 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); | |
| 8802 | 8803 | } |
| 8803 | 8804 | } |
| 8804 | 8805 | |
| ... | ... | @@ -12520,8 +12521,8 @@ FnTableEntry *ir_create_inline_fn(CodeGen *codegen, Buf *fn_name, VariableTableE |
| 12520 | 12521 | fn_entry->fndef_scope = create_fndef_scope(nullptr, parent_scope, fn_entry); |
| 12521 | 12522 | fn_entry->child_scope = &fn_entry->fndef_scope->base; |
| 12522 | 12523 | |
| 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; | |
| 12525 | 12526 | assert(src_fn_type->id == TypeTableEntryIdFn); |
| 12526 | 12527 | |
| 12527 | 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 | 1235 | // variable is non-null and calls it. |
| 1236 | 1236 | if (existing_tld->id == TldIdVar) { |
| 1237 | 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 | 1239 | if (var_type->id == TypeTableEntryIdMaybe && !tld_var->var->src_is_const) { |
| 1240 | 1240 | TypeTableEntry *child_type = var_type->data.maybe.child_type; |
| 1241 | 1241 | if (child_type->id == TypeTableEntryIdFn) { |
test/cases/array.zig+20-21| ... | ... | @@ -72,24 +72,23 @@ fn nestedArrays() { |
| 72 | 72 | } |
| 73 | 73 | |
| 74 | 74 | |
| 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 | //} | |
| 75 | var s_array: [8]Sub = undefined; | |
| 76 | const Sub = struct { | |
| 77 | b: u8, | |
| 78 | }; | |
| 79 | const Str = struct { | |
| 80 | a: []Sub, | |
| 81 | }; | |
| 82 | fn 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 | } |