mirror of
https://github.com/ziglang/zig.git
synced 2026-02-21 00:35:10 +00:00
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.
This commit is contained in:
parent
25761570f1
commit
1195994880
@ -1430,7 +1430,7 @@ enum VarLinkage {
|
||||
|
||||
struct VariableTableEntry {
|
||||
Buf name;
|
||||
ConstExprValue value;
|
||||
ConstExprValue *value;
|
||||
LLVMValueRef value_ref;
|
||||
bool src_is_const;
|
||||
bool gen_is_const;
|
||||
|
||||
@ -2085,7 +2085,7 @@ VariableTableEntry *add_variable(CodeGen *g, AstNode *source_node, Scope *parent
|
||||
assert(value);
|
||||
|
||||
VariableTableEntry *variable_entry = allocate<VariableTableEntry>(1);
|
||||
variable_entry->value = *value;
|
||||
variable_entry->value = value;
|
||||
variable_entry->parent_scope = parent_scope;
|
||||
variable_entry->shadowable = false;
|
||||
variable_entry->mem_slot_index = SIZE_MAX;
|
||||
@ -2101,21 +2101,21 @@ VariableTableEntry *add_variable(CodeGen *g, AstNode *source_node, Scope *parent
|
||||
ErrorMsg *msg = add_node_error(g, source_node,
|
||||
buf_sprintf("redeclaration of variable '%s'", buf_ptr(name)));
|
||||
add_error_note(g, msg, existing_var->decl_node, buf_sprintf("previous declaration is here"));
|
||||
variable_entry->value.type = g->builtin_types.entry_invalid;
|
||||
variable_entry->value->type = g->builtin_types.entry_invalid;
|
||||
} else {
|
||||
auto primitive_table_entry = g->primitive_type_table.maybe_get(name);
|
||||
if (primitive_table_entry) {
|
||||
TypeTableEntry *type = primitive_table_entry->value;
|
||||
add_node_error(g, source_node,
|
||||
buf_sprintf("variable shadows type '%s'", buf_ptr(&type->name)));
|
||||
variable_entry->value.type = g->builtin_types.entry_invalid;
|
||||
variable_entry->value->type = g->builtin_types.entry_invalid;
|
||||
} else {
|
||||
Tld *tld = find_decl(g, parent_scope, name);
|
||||
if (tld && tld->id != TldIdVar) {
|
||||
ErrorMsg *msg = add_node_error(g, source_node,
|
||||
buf_sprintf("redefinition of '%s'", buf_ptr(name)));
|
||||
add_error_note(g, msg, tld->source_node, buf_sprintf("previous definition is here"));
|
||||
variable_entry->value.type = g->builtin_types.entry_invalid;
|
||||
variable_entry->value->type = g->builtin_types.entry_invalid;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3181,7 +3181,7 @@ uint32_t fn_eval_hash(Scope* scope) {
|
||||
while (scope) {
|
||||
if (scope->id == ScopeIdVarDecl) {
|
||||
ScopeVarDecl *var_scope = (ScopeVarDecl *)scope;
|
||||
result += hash_const_val(&var_scope->var->value);
|
||||
result += hash_const_val(var_scope->var->value);
|
||||
} else if (scope->id == ScopeIdFnDef) {
|
||||
ScopeFnDef *fn_scope = (ScopeFnDef *)scope;
|
||||
result += hash_ptr(fn_scope->fn_entry);
|
||||
@ -3203,9 +3203,9 @@ bool fn_eval_eql(Scope *a, Scope *b) {
|
||||
if (a->id == ScopeIdVarDecl) {
|
||||
ScopeVarDecl *a_var_scope = (ScopeVarDecl *)a;
|
||||
ScopeVarDecl *b_var_scope = (ScopeVarDecl *)b;
|
||||
if (a_var_scope->var->value.type != b_var_scope->var->value.type)
|
||||
if (a_var_scope->var->value->type != b_var_scope->var->value->type)
|
||||
return false;
|
||||
if (!const_values_equal(&a_var_scope->var->value, &b_var_scope->var->value))
|
||||
if (!const_values_equal(a_var_scope->var->value, b_var_scope->var->value))
|
||||
return false;
|
||||
} else if (a->id == ScopeIdFnDef) {
|
||||
ScopeFnDef *a_fn_scope = (ScopeFnDef *)a;
|
||||
|
||||
@ -964,26 +964,26 @@ static void ast_render_tld_var(AstRender *ar, Buf *name, TldVar *tld_var) {
|
||||
const char *extern_str = extern_string(var->linkage == VarLinkageExternal);
|
||||
fprintf(ar->f, "%s%s%s %s", visib_mod_str, extern_str, const_or_var, buf_ptr(name));
|
||||
|
||||
if (var->value.type->id == TypeTableEntryIdNumLitFloat ||
|
||||
var->value.type->id == TypeTableEntryIdNumLitInt ||
|
||||
var->value.type->id == TypeTableEntryIdMetaType)
|
||||
if (var->value->type->id == TypeTableEntryIdNumLitFloat ||
|
||||
var->value->type->id == TypeTableEntryIdNumLitInt ||
|
||||
var->value->type->id == TypeTableEntryIdMetaType)
|
||||
{
|
||||
// skip type
|
||||
} else {
|
||||
fprintf(ar->f, ": %s", buf_ptr(&var->value.type->name));
|
||||
fprintf(ar->f, ": %s", buf_ptr(&var->value->type->name));
|
||||
}
|
||||
|
||||
if (var->value.special == ConstValSpecialRuntime) {
|
||||
if (var->value->special == ConstValSpecialRuntime) {
|
||||
fprintf(ar->f, ";\n");
|
||||
return;
|
||||
}
|
||||
|
||||
fprintf(ar->f, " = ");
|
||||
|
||||
if (var->value.special == ConstValSpecialStatic &&
|
||||
var->value.type->id == TypeTableEntryIdMetaType)
|
||||
if (var->value->special == ConstValSpecialStatic &&
|
||||
var->value->type->id == TypeTableEntryIdMetaType)
|
||||
{
|
||||
TypeTableEntry *type_entry = var->value.data.x_type;
|
||||
TypeTableEntry *type_entry = var->value->data.x_type;
|
||||
if (type_entry->id == TypeTableEntryIdStruct) {
|
||||
const char *layout_str = layout_string(type_entry->data.structure.layout);
|
||||
fprintf(ar->f, "%sstruct {\n", layout_str);
|
||||
@ -1022,7 +1022,7 @@ static void ast_render_tld_var(AstRender *ar, Buf *name, TldVar *tld_var) {
|
||||
} else {
|
||||
Buf buf = BUF_INIT;
|
||||
buf_resize(&buf, 0);
|
||||
render_const_value(&buf, &var->value);
|
||||
render_const_value(&buf, var->value);
|
||||
fprintf(ar->f, "%s", buf_ptr(&buf));
|
||||
}
|
||||
|
||||
|
||||
@ -1316,7 +1316,7 @@ static LLVMValueRef ir_render_decl_var(CodeGen *g, IrExecutable *executable,
|
||||
{
|
||||
VariableTableEntry *var = decl_var_instruction->var;
|
||||
|
||||
if (!type_has_bits(var->value.type))
|
||||
if (!type_has_bits(var->value->type))
|
||||
return nullptr;
|
||||
|
||||
if (var->ref_count == 0 && g->is_release_build)
|
||||
@ -1331,16 +1331,16 @@ static LLVMValueRef ir_render_decl_var(CodeGen *g, IrExecutable *executable,
|
||||
have_init_expr = true;
|
||||
|
||||
if (have_init_expr) {
|
||||
assert(var->value.type == init_value->value.type);
|
||||
gen_assign_raw(g, var->value_ref, ir_llvm_value(g, init_value), var->value.type);
|
||||
assert(var->value->type == init_value->value.type);
|
||||
gen_assign_raw(g, var->value_ref, ir_llvm_value(g, init_value), var->value->type);
|
||||
} else {
|
||||
bool ignore_uninit = false;
|
||||
// handle runtime stack allocation
|
||||
bool want_safe = ir_want_debug_safety(g, &decl_var_instruction->base);
|
||||
if (!ignore_uninit && want_safe) {
|
||||
TypeTableEntry *usize = g->builtin_types.entry_usize;
|
||||
uint64_t size_bytes = LLVMStoreSizeOfType(g->target_data_ref, var->value.type->type_ref);
|
||||
uint64_t align_bytes = get_type_alignment(g, var->value.type);
|
||||
uint64_t size_bytes = LLVMStoreSizeOfType(g->target_data_ref, var->value->type->type_ref);
|
||||
uint64_t align_bytes = get_type_alignment(g, var->value->type);
|
||||
|
||||
// memset uninitialized memory to 0xa
|
||||
LLVMTypeRef ptr_u8 = LLVMPointerType(LLVMInt8Type(), 0);
|
||||
@ -1437,7 +1437,7 @@ static LLVMValueRef ir_render_store_ptr(CodeGen *g, IrExecutable *executable, Ir
|
||||
|
||||
static LLVMValueRef ir_render_var_ptr(CodeGen *g, IrExecutable *executable, IrInstructionVarPtr *instruction) {
|
||||
VariableTableEntry *var = instruction->var;
|
||||
if (type_has_bits(var->value.type)) {
|
||||
if (type_has_bits(var->value->type)) {
|
||||
assert(var->value_ref);
|
||||
return var->value_ref;
|
||||
} else {
|
||||
@ -3203,9 +3203,9 @@ static void do_code_gen(CodeGen *g) {
|
||||
TldVar *tld_var = g->global_vars.at(i);
|
||||
VariableTableEntry *var = tld_var->var;
|
||||
|
||||
if (var->value.type->id == TypeTableEntryIdNumLitFloat) {
|
||||
if (var->value->type->id == TypeTableEntryIdNumLitFloat) {
|
||||
// Generate debug info for it but that's it.
|
||||
ConstExprValue *const_val = &var->value;
|
||||
ConstExprValue *const_val = var->value;
|
||||
assert(const_val->special != ConstValSpecialRuntime);
|
||||
TypeTableEntry *var_type = g->builtin_types.entry_f64;
|
||||
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) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (var->value.type->id == TypeTableEntryIdNumLitInt) {
|
||||
if (var->value->type->id == TypeTableEntryIdNumLitInt) {
|
||||
// Generate debug info for it but that's it.
|
||||
ConstExprValue *const_val = &var->value;
|
||||
ConstExprValue *const_val = var->value;
|
||||
assert(const_val->special != ConstValSpecialRuntime);
|
||||
TypeTableEntry *var_type = const_val->data.x_bignum.is_negative ?
|
||||
g->builtin_types.entry_isize : g->builtin_types.entry_usize;
|
||||
@ -3225,22 +3225,22 @@ static void do_code_gen(CodeGen *g) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!type_has_bits(var->value.type))
|
||||
if (!type_has_bits(var->value->type))
|
||||
continue;
|
||||
|
||||
assert(var->decl_node);
|
||||
|
||||
LLVMValueRef global_value;
|
||||
if (var->linkage == VarLinkageExternal) {
|
||||
global_value = LLVMAddGlobal(g->module, var->value.type->type_ref, buf_ptr(&var->name));
|
||||
global_value = LLVMAddGlobal(g->module, var->value->type->type_ref, buf_ptr(&var->name));
|
||||
|
||||
// TODO debug info for the extern variable
|
||||
|
||||
LLVMSetLinkage(global_value, LLVMExternalLinkage);
|
||||
} else {
|
||||
render_const_val(g, &var->value);
|
||||
render_const_val_global(g, &var->value, buf_ptr(&var->name));
|
||||
global_value = var->value.llvm_global;
|
||||
render_const_val(g, var->value);
|
||||
render_const_val_global(g, var->value, buf_ptr(&var->name));
|
||||
global_value = var->value->llvm_global;
|
||||
|
||||
if (var->linkage == VarLinkageExport) {
|
||||
LLVMSetLinkage(global_value, LLVMExternalLinkage);
|
||||
@ -3249,11 +3249,11 @@ static void do_code_gen(CodeGen *g) {
|
||||
LLVMSetSection(global_value, buf_ptr(tld_var->section_name));
|
||||
}
|
||||
LLVMSetAlignment(global_value, tld_var->alignment ?
|
||||
tld_var->alignment : get_type_alignment(g, var->value.type));
|
||||
tld_var->alignment : get_type_alignment(g, var->value->type));
|
||||
|
||||
// TODO debug info for function pointers
|
||||
if (var->gen_is_const && var->value.type->id != TypeTableEntryIdFn) {
|
||||
gen_global_var(g, var, var->value.llvm_value, var->value.type);
|
||||
if (var->gen_is_const && var->value->type->id != TypeTableEntryIdFn) {
|
||||
gen_global_var(g, var, var->value->llvm_value, var->value->type);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3432,30 +3432,30 @@ static void do_code_gen(CodeGen *g) {
|
||||
for (size_t var_i = 0; var_i < fn_table_entry->variable_list.length; var_i += 1) {
|
||||
VariableTableEntry *var = fn_table_entry->variable_list.at(var_i);
|
||||
|
||||
if (!type_has_bits(var->value.type)) {
|
||||
if (!type_has_bits(var->value->type)) {
|
||||
continue;
|
||||
}
|
||||
if (ir_get_var_is_comptime(var))
|
||||
continue;
|
||||
if (type_requires_comptime(var->value.type))
|
||||
if (type_requires_comptime(var->value->type))
|
||||
continue;
|
||||
|
||||
if (var->src_arg_index == SIZE_MAX) {
|
||||
var->value_ref = build_alloca(g, var->value.type, buf_ptr(&var->name));
|
||||
var->value_ref = build_alloca(g, var->value->type, buf_ptr(&var->name));
|
||||
|
||||
var->di_loc_var = ZigLLVMCreateAutoVariable(g->dbuilder, get_di_scope(g, var->parent_scope),
|
||||
buf_ptr(&var->name), import->di_file, var->decl_node->line + 1,
|
||||
var->value.type->di_type, !g->strip_debug_symbols, 0);
|
||||
var->value->type->di_type, !g->strip_debug_symbols, 0);
|
||||
|
||||
} else {
|
||||
assert(var->gen_arg_index != SIZE_MAX);
|
||||
TypeTableEntry *gen_type;
|
||||
if (handle_is_ptr(var->value.type)) {
|
||||
if (handle_is_ptr(var->value->type)) {
|
||||
gen_type = fn_table_entry->type_entry->data.fn.gen_param_info[var->src_arg_index].type;
|
||||
var->value_ref = LLVMGetParam(fn, var->gen_arg_index);
|
||||
} else {
|
||||
gen_type = var->value.type;
|
||||
var->value_ref = build_alloca(g, var->value.type, buf_ptr(&var->name));
|
||||
gen_type = var->value->type;
|
||||
var->value_ref = build_alloca(g, var->value->type, buf_ptr(&var->name));
|
||||
}
|
||||
if (var->decl_node) {
|
||||
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) {
|
||||
assert(variable);
|
||||
assert(variable->value_ref);
|
||||
|
||||
if (!handle_is_ptr(variable->value.type)) {
|
||||
if (!handle_is_ptr(variable->value->type)) {
|
||||
clear_debug_source_node(g);
|
||||
LLVMBuildStore(g->builder, LLVMGetParam(fn, variable->gen_arg_index), variable->value_ref);
|
||||
}
|
||||
|
||||
49
src/ir.cpp
49
src/ir.cpp
@ -3164,6 +3164,7 @@ static VariableTableEntry *create_local_var(CodeGen *codegen, AstNode *node, Sco
|
||||
variable_entry->mem_slot_index = SIZE_MAX;
|
||||
variable_entry->is_comptime = is_comptime;
|
||||
variable_entry->src_arg_index = SIZE_MAX;
|
||||
variable_entry->value = allocate<ConstExprValue>(1);
|
||||
|
||||
if (name) {
|
||||
buf_init_from_buf(&variable_entry->name, name);
|
||||
@ -3173,21 +3174,21 @@ static VariableTableEntry *create_local_var(CodeGen *codegen, AstNode *node, Sco
|
||||
ErrorMsg *msg = add_node_error(codegen, node,
|
||||
buf_sprintf("redeclaration of variable '%s'", buf_ptr(name)));
|
||||
add_error_note(codegen, msg, existing_var->decl_node, buf_sprintf("previous declaration is here"));
|
||||
variable_entry->value.type = codegen->builtin_types.entry_invalid;
|
||||
variable_entry->value->type = codegen->builtin_types.entry_invalid;
|
||||
} else {
|
||||
auto primitive_table_entry = codegen->primitive_type_table.maybe_get(name);
|
||||
if (primitive_table_entry) {
|
||||
TypeTableEntry *type = primitive_table_entry->value;
|
||||
add_node_error(codegen, node,
|
||||
buf_sprintf("variable shadows type '%s'", buf_ptr(&type->name)));
|
||||
variable_entry->value.type = codegen->builtin_types.entry_invalid;
|
||||
variable_entry->value->type = codegen->builtin_types.entry_invalid;
|
||||
} else {
|
||||
Tld *tld = find_decl(codegen, parent_scope, name);
|
||||
if (tld && tld->id != TldIdVar) {
|
||||
ErrorMsg *msg = add_node_error(codegen, node,
|
||||
buf_sprintf("redefinition of '%s'", buf_ptr(name)));
|
||||
add_error_note(codegen, msg, tld->source_node, buf_sprintf("previous definition is here"));
|
||||
variable_entry->value.type = codegen->builtin_types.entry_invalid;
|
||||
variable_entry->value->type = codegen->builtin_types.entry_invalid;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -4516,7 +4517,7 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, Scope *scope, AstNode *nod
|
||||
// is inside var->child_scope
|
||||
|
||||
if (!is_extern && !variable_declaration->expr) {
|
||||
var->value.type = irb->codegen->builtin_types.entry_invalid;
|
||||
var->value->type = irb->codegen->builtin_types.entry_invalid;
|
||||
add_node_error(irb->codegen, node, buf_sprintf("variables must be initialized"));
|
||||
return irb->codegen->invalid_instruction;
|
||||
}
|
||||
@ -5387,7 +5388,7 @@ static bool render_instance_name_recursive(Buf *name, Scope *outer_scope, Scope
|
||||
ScopeVarDecl *var_scope = (ScopeVarDecl *)inner_scope;
|
||||
if (need_comma)
|
||||
buf_append_char(name, ',');
|
||||
render_const_value(name, &var_scope->var->value);
|
||||
render_const_value(name, var_scope->var->value);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -7827,8 +7828,8 @@ static TypeTableEntry *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstruc
|
||||
|
||||
IrInstruction *init_value = decl_var_instruction->init_value->other;
|
||||
if (type_is_invalid(init_value->value.type)) {
|
||||
var->value.type = ira->codegen->builtin_types.entry_invalid;
|
||||
return var->value.type;
|
||||
var->value->type = ira->codegen->builtin_types.entry_invalid;
|
||||
return var->value->type;
|
||||
}
|
||||
|
||||
AstNodeVariableDeclaration *variable_declaration = &var->decl_node->data.variable_declaration;
|
||||
@ -7844,8 +7845,8 @@ static TypeTableEntry *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstruc
|
||||
TypeTableEntry *proposed_type = ir_resolve_type(ira, var_type);
|
||||
explicit_type = validate_var_type(ira->codegen, var_type->source_node, proposed_type);
|
||||
if (type_is_invalid(explicit_type)) {
|
||||
var->value.type = ira->codegen->builtin_types.entry_invalid;
|
||||
return var->value.type;
|
||||
var->value->type = ira->codegen->builtin_types.entry_invalid;
|
||||
return var->value->type;
|
||||
}
|
||||
}
|
||||
|
||||
@ -7906,8 +7907,8 @@ static TypeTableEntry *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstruc
|
||||
break;
|
||||
}
|
||||
|
||||
var->value.type = result_type;
|
||||
assert(var->value.type);
|
||||
var->value->type = result_type;
|
||||
assert(var->value->type);
|
||||
|
||||
if (type_is_invalid(result_type)) {
|
||||
decl_var_instruction->base.other = &decl_var_instruction->base;
|
||||
@ -7930,7 +7931,7 @@ static TypeTableEntry *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstruc
|
||||
} else if (is_comptime) {
|
||||
ir_add_error(ira, &decl_var_instruction->base,
|
||||
buf_sprintf("cannot store runtime value in compile time variable"));
|
||||
var->value.type = ira->codegen->builtin_types.entry_invalid;
|
||||
var->value->type = ira->codegen->builtin_types.entry_invalid;
|
||||
return ira->codegen->builtin_types.entry_invalid;
|
||||
}
|
||||
|
||||
@ -8766,24 +8767,24 @@ static TypeTableEntry *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionP
|
||||
static TypeTableEntry *ir_analyze_var_ptr(IrAnalyze *ira, IrInstruction *instruction,
|
||||
VariableTableEntry *var, bool is_const_ptr, bool is_volatile_ptr)
|
||||
{
|
||||
assert(var->value.type);
|
||||
if (type_is_invalid(var->value.type))
|
||||
return var->value.type;
|
||||
assert(var->value->type);
|
||||
if (type_is_invalid(var->value->type))
|
||||
return var->value->type;
|
||||
|
||||
bool comptime_var_mem = ir_get_var_is_comptime(var);
|
||||
|
||||
ConstExprValue *mem_slot = nullptr;
|
||||
FnTableEntry *fn_entry = scope_fn_entry(var->parent_scope);
|
||||
if (var->value.special == ConstValSpecialStatic) {
|
||||
mem_slot = &var->value;
|
||||
if (var->value->special == ConstValSpecialStatic) {
|
||||
mem_slot = var->value;
|
||||
} else if (fn_entry) {
|
||||
// TODO once the analyze code is fully ported over to IR we won't need this SIZE_MAX thing.
|
||||
if (var->mem_slot_index != SIZE_MAX && (comptime_var_mem || var->gen_is_const))
|
||||
mem_slot = &ira->exec_context.mem_slot_list[var->mem_slot_index];
|
||||
}
|
||||
|
||||
bool is_const = (var->value.type->id == TypeTableEntryIdMetaType) ? is_const_ptr : var->src_is_const;
|
||||
bool is_volatile = (var->value.type->id == TypeTableEntryIdMetaType) ? is_volatile_ptr : false;
|
||||
bool is_const = (var->value->type->id == TypeTableEntryIdMetaType) ? is_const_ptr : var->src_is_const;
|
||||
bool is_volatile = (var->value->type->id == TypeTableEntryIdMetaType) ? is_volatile_ptr : false;
|
||||
if (mem_slot && mem_slot->special != ConstValSpecialRuntime) {
|
||||
ConstPtrMut ptr_mut;
|
||||
if (comptime_var_mem) {
|
||||
@ -8794,11 +8795,11 @@ static TypeTableEntry *ir_analyze_var_ptr(IrAnalyze *ira, IrInstruction *instruc
|
||||
assert(!comptime_var_mem);
|
||||
ptr_mut = ConstPtrMutRuntimeVar;
|
||||
}
|
||||
return ir_analyze_const_ptr(ira, instruction, mem_slot, var->value.type, ptr_mut, is_const, is_volatile);
|
||||
return ir_analyze_const_ptr(ira, instruction, mem_slot, var->value->type, ptr_mut, is_const, is_volatile);
|
||||
} else {
|
||||
ir_build_var_ptr_from(&ira->new_irb, instruction, var, is_const, is_volatile);
|
||||
type_ensure_zero_bits_known(ira->codegen, var->value.type);
|
||||
return get_pointer_to_type(ira->codegen, var->value.type, var->src_is_const);
|
||||
type_ensure_zero_bits_known(ira->codegen, var->value->type);
|
||||
return get_pointer_to_type(ira->codegen, var->value->type, var->src_is_const);
|
||||
}
|
||||
}
|
||||
|
||||
@ -12520,8 +12521,8 @@ FnTableEntry *ir_create_inline_fn(CodeGen *codegen, Buf *fn_name, VariableTableE
|
||||
fn_entry->fndef_scope = create_fndef_scope(nullptr, parent_scope, fn_entry);
|
||||
fn_entry->child_scope = &fn_entry->fndef_scope->base;
|
||||
|
||||
assert(var->value.type->id == TypeTableEntryIdMaybe);
|
||||
TypeTableEntry *src_fn_type = var->value.type->data.maybe.child_type;
|
||||
assert(var->value->type->id == TypeTableEntryIdMaybe);
|
||||
TypeTableEntry *src_fn_type = var->value->type->data.maybe.child_type;
|
||||
assert(src_fn_type->id == TypeTableEntryIdFn);
|
||||
|
||||
FnTypeId new_fn_type = src_fn_type->data.fn.fn_type_id;
|
||||
|
||||
@ -1235,7 +1235,7 @@ static void process_symbol_macros(Context *c) {
|
||||
// variable is non-null and calls it.
|
||||
if (existing_tld->id == TldIdVar) {
|
||||
TldVar *tld_var = (TldVar *)existing_tld;
|
||||
TypeTableEntry *var_type = tld_var->var->value.type;
|
||||
TypeTableEntry *var_type = tld_var->var->value->type;
|
||||
if (var_type->id == TypeTableEntryIdMaybe && !tld_var->var->src_is_const) {
|
||||
TypeTableEntry *child_type = var_type->data.maybe.child_type;
|
||||
if (child_type->id == TypeTableEntryIdFn) {
|
||||
|
||||
@ -72,24 +72,23 @@ fn nestedArrays() {
|
||||
}
|
||||
|
||||
|
||||
// TODO
|
||||
//var s_array: [8]Sub = undefined;
|
||||
//const Sub = struct {
|
||||
// b: u8,
|
||||
//};
|
||||
//const Str = struct {
|
||||
// a: []Sub,
|
||||
//};
|
||||
//fn setGlobalVarArrayViaSliceEmbeddedInStruct() {
|
||||
// @setFnTest(this);
|
||||
//
|
||||
// var s = Str { .a = s_array[0...]};
|
||||
//
|
||||
// s.a[0].b = 1;
|
||||
// s.a[1].b = 2;
|
||||
// s.a[2].b = 3;
|
||||
//
|
||||
// assert(s_array[0].b == 1);
|
||||
// assert(s_array[1].b == 2);
|
||||
// assert(s_array[2].b == 3);
|
||||
//}
|
||||
var s_array: [8]Sub = undefined;
|
||||
const Sub = struct {
|
||||
b: u8,
|
||||
};
|
||||
const Str = struct {
|
||||
a: []Sub,
|
||||
};
|
||||
fn setGlobalVarArrayViaSliceEmbeddedInStruct() {
|
||||
@setFnTest(this);
|
||||
|
||||
var s = Str { .a = s_array[0...]};
|
||||
|
||||
s.a[0].b = 1;
|
||||
s.a[1].b = 2;
|
||||
s.a[2].b = 3;
|
||||
|
||||
assert(s_array[0].b == 1);
|
||||
assert(s_array[1].b == 2);
|
||||
assert(s_array[2].b == 3);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user