Commit 2dfb1ebee2
Changed files (8)
src/all_types.hpp
@@ -210,11 +210,15 @@ struct ConstFn {
FnTableEntry *fn_entry;
};
+struct ConstGlobalRefs {
+ LLVMValueRef llvm_value;
+ LLVMValueRef llvm_global;
+};
+
struct ConstExprValue {
TypeTableEntry *type;
ConstValSpecial special;
- LLVMValueRef llvm_value;
- LLVMValueRef llvm_global;
+ ConstGlobalRefs *global_refs;
union {
// populated if special == ConstValSpecialStatic
@@ -527,6 +531,7 @@ enum CastOp {
CastOpBoolToInt,
CastOpResizeSlice,
CastOpBytesToSlice,
+ CastOpNumLitToConcrete,
};
struct AstNodeFnCallExpr {
src/analyze.cpp
@@ -3457,7 +3457,7 @@ bool type_requires_comptime(TypeTableEntry *type_entry) {
void init_const_str_lit(CodeGen *g, ConstExprValue *const_val, Buf *str) {
const_val->special = ConstValSpecialStatic;
const_val->type = get_array_type(g, g->builtin_types.entry_u8, buf_len(str));
- const_val->data.x_array.s_none.elements = allocate<ConstExprValue>(buf_len(str));
+ const_val->data.x_array.s_none.elements = create_const_vals(buf_len(str));
for (size_t i = 0; i < buf_len(str); i += 1) {
ConstExprValue *this_char = &const_val->data.x_array.s_none.elements[i];
@@ -3468,7 +3468,7 @@ void init_const_str_lit(CodeGen *g, ConstExprValue *const_val, Buf *str) {
}
ConstExprValue *create_const_str_lit(CodeGen *g, Buf *str) {
- ConstExprValue *const_val = allocate<ConstExprValue>(1);
+ ConstExprValue *const_val = create_const_vals(1);
init_const_str_lit(g, const_val, str);
return const_val;
}
@@ -3476,10 +3476,10 @@ ConstExprValue *create_const_str_lit(CodeGen *g, Buf *str) {
void init_const_c_str_lit(CodeGen *g, ConstExprValue *const_val, Buf *str) {
// first we build the underlying array
size_t len_with_null = buf_len(str) + 1;
- ConstExprValue *array_val = allocate<ConstExprValue>(1);
+ ConstExprValue *array_val = create_const_vals(1);
array_val->special = ConstValSpecialStatic;
array_val->type = get_array_type(g, g->builtin_types.entry_u8, len_with_null);
- array_val->data.x_array.s_none.elements = allocate<ConstExprValue>(len_with_null);
+ array_val->data.x_array.s_none.elements = create_const_vals(len_with_null);
for (size_t i = 0; i < buf_len(str); i += 1) {
ConstExprValue *this_char = &array_val->data.x_array.s_none.elements[i];
this_char->special = ConstValSpecialStatic;
@@ -3500,7 +3500,7 @@ void init_const_c_str_lit(CodeGen *g, ConstExprValue *const_val, Buf *str) {
const_val->data.x_ptr.data.base_array.is_cstr = true;
}
ConstExprValue *create_const_c_str_lit(CodeGen *g, Buf *str) {
- ConstExprValue *const_val = allocate<ConstExprValue>(1);
+ ConstExprValue *const_val = create_const_vals(1);
init_const_c_str_lit(g, const_val, str);
return const_val;
}
@@ -3513,7 +3513,7 @@ void init_const_unsigned_negative(ConstExprValue *const_val, TypeTableEntry *typ
}
ConstExprValue *create_const_unsigned_negative(TypeTableEntry *type, uint64_t x, bool negative) {
- ConstExprValue *const_val = allocate<ConstExprValue>(1);
+ ConstExprValue *const_val = create_const_vals(1);
init_const_unsigned_negative(const_val, type, x, negative);
return const_val;
}
@@ -3533,7 +3533,7 @@ void init_const_signed(ConstExprValue *const_val, TypeTableEntry *type, int64_t
}
ConstExprValue *create_const_signed(TypeTableEntry *type, int64_t x) {
- ConstExprValue *const_val = allocate<ConstExprValue>(1);
+ ConstExprValue *const_val = create_const_vals(1);
init_const_signed(const_val, type, x);
return const_val;
}
@@ -3545,7 +3545,7 @@ void init_const_float(ConstExprValue *const_val, TypeTableEntry *type, double va
}
ConstExprValue *create_const_float(TypeTableEntry *type, double value) {
- ConstExprValue *const_val = allocate<ConstExprValue>(1);
+ ConstExprValue *const_val = create_const_vals(1);
init_const_float(const_val, type, value);
return const_val;
}
@@ -3557,7 +3557,7 @@ void init_const_enum_tag(ConstExprValue *const_val, TypeTableEntry *type, uint64
}
ConstExprValue *create_const_enum_tag(TypeTableEntry *type, uint64_t tag) {
- ConstExprValue *const_val = allocate<ConstExprValue>(1);
+ ConstExprValue *const_val = create_const_vals(1);
init_const_enum_tag(const_val, type, tag);
return const_val;
}
@@ -3569,7 +3569,7 @@ void init_const_bool(CodeGen *g, ConstExprValue *const_val, bool value) {
}
ConstExprValue *create_const_bool(CodeGen *g, bool value) {
- ConstExprValue *const_val = allocate<ConstExprValue>(1);
+ ConstExprValue *const_val = create_const_vals(1);
init_const_bool(g, const_val, value);
return const_val;
}
@@ -3580,7 +3580,7 @@ void init_const_runtime(ConstExprValue *const_val, TypeTableEntry *type) {
}
ConstExprValue *create_const_runtime(TypeTableEntry *type) {
- ConstExprValue *const_val = allocate<ConstExprValue>(1);
+ ConstExprValue *const_val = create_const_vals(1);
init_const_runtime(const_val, type);
return const_val;
}
@@ -3592,7 +3592,7 @@ void init_const_type(CodeGen *g, ConstExprValue *const_val, TypeTableEntry *type
}
ConstExprValue *create_const_type(CodeGen *g, TypeTableEntry *type_value) {
- ConstExprValue *const_val = allocate<ConstExprValue>(1);
+ ConstExprValue *const_val = create_const_vals(1);
init_const_type(g, const_val, type_value);
return const_val;
}
@@ -3604,14 +3604,14 @@ void init_const_slice(CodeGen *g, ConstExprValue *const_val, ConstExprValue *arr
const_val->special = ConstValSpecialStatic;
const_val->type = get_slice_type(g, array_val->type->data.array.child_type, is_const);
- const_val->data.x_struct.fields = allocate<ConstExprValue>(2);
+ const_val->data.x_struct.fields = create_const_vals(2);
init_const_ptr_array(g, &const_val->data.x_struct.fields[slice_ptr_index], array_val, start, is_const);
init_const_usize(g, &const_val->data.x_struct.fields[slice_len_index], len);
}
ConstExprValue *create_const_slice(CodeGen *g, ConstExprValue *array_val, size_t start, size_t len, bool is_const) {
- ConstExprValue *const_val = allocate<ConstExprValue>(1);
+ ConstExprValue *const_val = create_const_vals(1);
init_const_slice(g, const_val, array_val, start, len, is_const);
return const_val;
}
@@ -3630,7 +3630,7 @@ void init_const_ptr_array(CodeGen *g, ConstExprValue *const_val, ConstExprValue
}
ConstExprValue *create_const_ptr_array(CodeGen *g, ConstExprValue *array_val, size_t elem_index, bool is_const) {
- ConstExprValue *const_val = allocate<ConstExprValue>(1);
+ ConstExprValue *const_val = create_const_vals(1);
init_const_ptr_array(g, const_val, array_val, elem_index, is_const);
return const_val;
}
@@ -3643,7 +3643,7 @@ void init_const_ptr_ref(CodeGen *g, ConstExprValue *const_val, ConstExprValue *p
}
ConstExprValue *create_const_ptr_ref(CodeGen *g, ConstExprValue *pointee_val, bool is_const) {
- ConstExprValue *const_val = allocate<ConstExprValue>(1);
+ ConstExprValue *const_val = create_const_vals(1);
init_const_ptr_ref(g, const_val, pointee_val, is_const);
return const_val;
}
@@ -3660,7 +3660,7 @@ void init_const_ptr_hard_coded_addr(CodeGen *g, ConstExprValue *const_val, TypeT
ConstExprValue *create_const_ptr_hard_coded_addr(CodeGen *g, TypeTableEntry *pointee_type,
size_t addr, bool is_const)
{
- ConstExprValue *const_val = allocate<ConstExprValue>(1);
+ ConstExprValue *const_val = create_const_vals(1);
init_const_ptr_hard_coded_addr(g, const_val, pointee_type, addr, is_const);
return const_val;
}
@@ -3673,7 +3673,7 @@ void init_const_arg_tuple(CodeGen *g, ConstExprValue *const_val, size_t arg_inde
}
ConstExprValue *create_const_arg_tuple(CodeGen *g, size_t arg_index_start, size_t arg_index_end) {
- ConstExprValue *const_val = allocate<ConstExprValue>(1);
+ ConstExprValue *const_val = create_const_vals(1);
init_const_arg_tuple(g, const_val, arg_index_start, arg_index_end);
return const_val;
}
@@ -3689,7 +3689,7 @@ void init_const_undefined(CodeGen *g, ConstExprValue *const_val) {
const_val->special = ConstValSpecialStatic;
size_t field_count = wanted_type->data.structure.src_field_count;
- const_val->data.x_struct.fields = allocate<ConstExprValue>(field_count);
+ const_val->data.x_struct.fields = create_const_vals(field_count);
for (size_t i = 0; i < field_count; i += 1) {
ConstExprValue *field_val = &const_val->data.x_struct.fields[i];
field_val->type = wanted_type->data.structure.fields[i].type_entry;
@@ -3707,6 +3707,15 @@ void init_const_undefined(CodeGen *g, ConstExprValue *const_val) {
}
}
+ConstExprValue *create_const_vals(size_t count) {
+ ConstGlobalRefs *global_refs = allocate<ConstGlobalRefs>(count);
+ ConstExprValue *vals = allocate<ConstExprValue>(count);
+ for (size_t i = 0; i < count; i += 1) {
+ vals[i].global_refs = &global_refs[i];
+ }
+ return vals;
+}
+
void ensure_complete_type(CodeGen *g, TypeTableEntry *type_entry) {
if (type_entry->id == TypeTableEntryIdStruct) {
if (!type_entry->data.structure.complete)
@@ -3788,16 +3797,24 @@ bool const_values_equal(ConstExprValue *a, ConstExprValue *b) {
return false;
return true;
case ConstPtrSpecialBaseArray:
- if (a->data.x_ptr.data.base_array.array_val != b->data.x_ptr.data.base_array.array_val)
+ if (a->data.x_ptr.data.base_array.array_val != b->data.x_ptr.data.base_array.array_val &&
+ a->data.x_ptr.data.base_array.array_val->global_refs !=
+ b->data.x_ptr.data.base_array.array_val->global_refs)
+ {
return false;
+ }
if (a->data.x_ptr.data.base_array.elem_index != b->data.x_ptr.data.base_array.elem_index)
return false;
if (a->data.x_ptr.data.base_array.is_cstr != b->data.x_ptr.data.base_array.is_cstr)
return false;
return true;
case ConstPtrSpecialBaseStruct:
- if (a->data.x_ptr.data.base_struct.struct_val != b->data.x_ptr.data.base_struct.struct_val)
+ if (a->data.x_ptr.data.base_struct.struct_val != b->data.x_ptr.data.base_struct.struct_val &&
+ a->data.x_ptr.data.base_struct.struct_val->global_refs !=
+ b->data.x_ptr.data.base_struct.struct_val->global_refs)
+ {
return false;
+ }
if (a->data.x_ptr.data.base_struct.field_index != b->data.x_ptr.data.base_struct.field_index)
return false;
return true;
@@ -4293,7 +4310,7 @@ void expand_undef_array(CodeGen *g, ConstExprValue *const_val) {
if (const_val->data.x_array.special == ConstArraySpecialUndef) {
const_val->data.x_array.special = ConstArraySpecialNone;
size_t elem_count = const_val->type->data.array.len;
- const_val->data.x_array.s_none.elements = allocate<ConstExprValue>(elem_count);
+ const_val->data.x_array.s_none.elements = create_const_vals(elem_count);
for (size_t i = 0; i < elem_count; i += 1) {
ConstExprValue *element_val = &const_val->data.x_array.s_none.elements[i];
element_val->type = const_val->type->data.array.child_type;
src/analyze.hpp
@@ -153,6 +153,8 @@ ConstExprValue *create_const_arg_tuple(CodeGen *g, size_t arg_index_start, size_
void init_const_undefined(CodeGen *g, ConstExprValue *const_val);
+ConstExprValue *create_const_vals(size_t count);
+
TypeTableEntry *make_int_type(CodeGen *g, bool is_signed, uint32_t size_in_bits);
ConstParent *get_const_val_parent(CodeGen *g, ConstExprValue *value);
FnTableEntry *get_extern_panic_fn(CodeGen *g);
src/codegen.cpp
@@ -682,8 +682,8 @@ static Buf *panic_msg_buf(PanicMsgId msg_id) {
static LLVMValueRef get_panic_msg_ptr_val(CodeGen *g, PanicMsgId msg_id) {
ConstExprValue *val = &g->panic_msg_vals[msg_id];
- if (val->llvm_global)
- return val->llvm_global;
+ if (val->global_refs->llvm_global)
+ return val->global_refs->llvm_global;
Buf *buf_msg = panic_msg_buf(msg_id);
ConstExprValue *array_val = create_const_str_lit(g, buf_msg);
@@ -692,8 +692,8 @@ static LLVMValueRef get_panic_msg_ptr_val(CodeGen *g, PanicMsgId msg_id) {
render_const_val_global(g, val, "");
render_const_val(g, val);
- assert(val->llvm_global);
- return val->llvm_global;
+ assert(val->global_refs->llvm_global);
+ return val->global_refs->llvm_global;
}
static void gen_panic_raw(CodeGen *g, LLVMValueRef msg_ptr, LLVMValueRef msg_len) {
@@ -1086,11 +1086,11 @@ static LLVMValueRef ir_llvm_value(CodeGen *g, IrInstruction *instruction) {
if (handle_is_ptr(instruction->value.type)) {
render_const_val_global(g, &instruction->value, "");
TypeTableEntry *ptr_type = get_pointer_to_type(g, instruction->value.type, true);
- instruction->llvm_value = LLVMBuildBitCast(g->builder, instruction->value.llvm_global, ptr_type->type_ref, "");
+ instruction->llvm_value = LLVMBuildBitCast(g->builder, instruction->value.global_refs->llvm_global, ptr_type->type_ref, "");
} else if (instruction->value.type->id == TypeTableEntryIdPointer) {
- instruction->llvm_value = LLVMBuildBitCast(g->builder, instruction->value.llvm_value, instruction->value.type->type_ref, "");
+ instruction->llvm_value = LLVMBuildBitCast(g->builder, instruction->value.global_refs->llvm_value, instruction->value.type->type_ref, "");
} else {
- instruction->llvm_value = instruction->value.llvm_value;
+ instruction->llvm_value = instruction->value.global_refs->llvm_value;
}
assert(instruction->llvm_value);
}
@@ -1535,6 +1535,7 @@ static LLVMValueRef ir_render_cast(CodeGen *g, IrExecutable *executable,
switch (cast_instruction->cast_op) {
case CastOpNoCast:
+ case CastOpNumLitToConcrete:
zig_unreachable();
case CastOpNoop:
return expr_val;
@@ -3197,7 +3198,7 @@ static LLVMValueRef gen_parent_ptr(CodeGen *g, ConstExprValue *val, ConstParent
case ConstParentIdNone:
render_const_val(g, val);
render_const_val_global(g, val, "");
- return val->llvm_global;
+ return val->global_refs->llvm_global;
case ConstParentIdStruct:
return gen_const_ptr_struct_recursive(g, parent->data.p_struct.struct_val,
parent->data.p_struct.field_index);
@@ -3506,9 +3507,9 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) {
render_const_val(g, pointee);
render_const_val_global(g, pointee, "");
ConstExprValue *other_val = pointee;
- const_val->llvm_value = LLVMConstBitCast(other_val->llvm_global, const_val->type->type_ref);
+ const_val->global_refs->llvm_value = LLVMConstBitCast(other_val->global_refs->llvm_global, const_val->type->type_ref);
render_const_val_global(g, const_val, "");
- return const_val->llvm_value;
+ return const_val->global_refs->llvm_value;
}
case ConstPtrSpecialBaseArray:
{
@@ -3518,15 +3519,15 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) {
if (array_const_val->type->zero_bits) {
// make this a null pointer
TypeTableEntry *usize = g->builtin_types.entry_usize;
- const_val->llvm_value = LLVMConstIntToPtr(LLVMConstNull(usize->type_ref),
+ const_val->global_refs->llvm_value = LLVMConstIntToPtr(LLVMConstNull(usize->type_ref),
const_val->type->type_ref);
render_const_val_global(g, const_val, "");
- return const_val->llvm_value;
+ return const_val->global_refs->llvm_value;
}
LLVMValueRef uncasted_ptr_val = gen_const_ptr_array_recursive(g, array_const_val,
elem_index);
LLVMValueRef ptr_val = LLVMConstBitCast(uncasted_ptr_val, const_val->type->type_ref);
- const_val->llvm_value = ptr_val;
+ const_val->global_refs->llvm_value = ptr_val;
render_const_val_global(g, const_val, "");
return ptr_val;
}
@@ -3537,10 +3538,10 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) {
if (struct_const_val->type->zero_bits) {
// make this a null pointer
TypeTableEntry *usize = g->builtin_types.entry_usize;
- const_val->llvm_value = LLVMConstIntToPtr(LLVMConstNull(usize->type_ref),
+ const_val->global_refs->llvm_value = LLVMConstIntToPtr(LLVMConstNull(usize->type_ref),
const_val->type->type_ref);
render_const_val_global(g, const_val, "");
- return const_val->llvm_value;
+ return const_val->global_refs->llvm_value;
}
size_t src_field_index = const_val->data.x_ptr.data.base_struct.field_index;
size_t gen_field_index =
@@ -3548,7 +3549,7 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) {
LLVMValueRef uncasted_ptr_val = gen_const_ptr_struct_recursive(g, struct_const_val,
gen_field_index);
LLVMValueRef ptr_val = LLVMConstBitCast(uncasted_ptr_val, const_val->type->type_ref);
- const_val->llvm_value = ptr_val;
+ const_val->global_refs->llvm_value = ptr_val;
render_const_val_global(g, const_val, "");
return ptr_val;
}
@@ -3556,10 +3557,10 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) {
{
uint64_t addr_value = const_val->data.x_ptr.data.hard_coded_addr.addr;
TypeTableEntry *usize = g->builtin_types.entry_usize;
- const_val->llvm_value = LLVMConstIntToPtr(LLVMConstInt(usize->type_ref, addr_value, false),
+ const_val->global_refs->llvm_value = LLVMConstIntToPtr(LLVMConstInt(usize->type_ref, addr_value, false),
const_val->type->type_ref);
render_const_val_global(g, const_val, "");
- return const_val->llvm_value;
+ return const_val->global_refs->llvm_value;
}
}
}
@@ -3608,27 +3609,32 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) {
}
static void render_const_val(CodeGen *g, ConstExprValue *const_val) {
- if (!const_val->llvm_value)
- const_val->llvm_value = gen_const_val(g, const_val);
+ if (!const_val->global_refs)
+ const_val->global_refs = allocate<ConstGlobalRefs>(1);
+ if (!const_val->global_refs->llvm_value)
+ const_val->global_refs->llvm_value = gen_const_val(g, const_val);
- if (const_val->llvm_global)
- LLVMSetInitializer(const_val->llvm_global, const_val->llvm_value);
+ if (const_val->global_refs->llvm_global)
+ LLVMSetInitializer(const_val->global_refs->llvm_global, const_val->global_refs->llvm_value);
}
static void render_const_val_global(CodeGen *g, ConstExprValue *const_val, const char *name) {
- if (!const_val->llvm_global) {
- LLVMTypeRef type_ref = const_val->llvm_value ? LLVMTypeOf(const_val->llvm_value) : const_val->type->type_ref;
+ if (!const_val->global_refs)
+ const_val->global_refs = allocate<ConstGlobalRefs>(1);
+
+ if (!const_val->global_refs->llvm_global) {
+ LLVMTypeRef type_ref = const_val->global_refs->llvm_value ? LLVMTypeOf(const_val->global_refs->llvm_value) : const_val->type->type_ref;
LLVMValueRef global_value = LLVMAddGlobal(g->module, type_ref, name);
LLVMSetLinkage(global_value, LLVMInternalLinkage);
LLVMSetGlobalConstant(global_value, true);
LLVMSetUnnamedAddr(global_value, true);
LLVMSetAlignment(global_value, get_type_alignment(g, const_val->type));
- const_val->llvm_global = global_value;
+ const_val->global_refs->llvm_global = global_value;
}
- if (const_val->llvm_value)
- LLVMSetInitializer(const_val->llvm_global, const_val->llvm_value);
+ if (const_val->global_refs->llvm_value)
+ LLVMSetInitializer(const_val->global_refs->llvm_global, const_val->global_refs->llvm_value);
}
static void delete_unused_builtin_fns(CodeGen *g) {
@@ -3849,7 +3855,7 @@ static void do_code_gen(CodeGen *g) {
bool exported = (var->linkage == VarLinkageExport);
render_const_val(g, var->value);
render_const_val_global(g, var->value, buf_ptr(get_mangled_name(g, &var->name, exported)));
- global_value = var->value->llvm_global;
+ global_value = var->value->global_refs->llvm_global;
if (exported) {
LLVMSetLinkage(global_value, LLVMExternalLinkage);
@@ -3862,7 +3868,7 @@ static void do_code_gen(CodeGen *g) {
// 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);
+ gen_global_var(g, var, var->value->global_refs->llvm_value, var->value->type);
}
}
@@ -4737,9 +4743,18 @@ static void init(CodeGen *g) {
g->invalid_instruction = allocate<IrInstruction>(1);
g->invalid_instruction->value.type = g->builtin_types.entry_invalid;
+ g->invalid_instruction->value.global_refs = allocate<ConstGlobalRefs>(1);
g->const_void_val.special = ConstValSpecialStatic;
g->const_void_val.type = g->builtin_types.entry_void;
+ g->const_void_val.global_refs = allocate<ConstGlobalRefs>(1);
+
+ {
+ ConstGlobalRefs *global_refs = allocate<ConstGlobalRefs>(PanicMsgIdCount);
+ for (size_t i = 0; i < PanicMsgIdCount; i += 1) {
+ g->panic_msg_vals[i].global_refs = &global_refs[i];
+ }
+ }
define_builtin_fns(g);
define_builtin_compile_vars(g);
@@ -4826,10 +4841,10 @@ static void create_test_compile_var_and_add_test_runner(CodeGen *g) {
TypeTableEntry *field_types[] = { str_type, fn_type, };
TypeTableEntry *struct_type = get_struct_type(g, "ZigTestFn", field_names, field_types, 2);
- ConstExprValue *test_fn_array = allocate<ConstExprValue>(1);
+ ConstExprValue *test_fn_array = create_const_vals(1);
test_fn_array->type = get_array_type(g, struct_type, g->test_fns.length);
test_fn_array->special = ConstValSpecialStatic;
- test_fn_array->data.x_array.s_none.elements = allocate<ConstExprValue>(g->test_fns.length);
+ test_fn_array->data.x_array.s_none.elements = create_const_vals(g->test_fns.length);
for (size_t i = 0; i < g->test_fns.length; i += 1) {
FnTableEntry *test_fn_entry = g->test_fns.at(i);
@@ -4840,7 +4855,7 @@ static void create_test_compile_var_and_add_test_runner(CodeGen *g) {
this_val->data.x_struct.parent.id = ConstParentIdArray;
this_val->data.x_struct.parent.data.p_array.array_val = test_fn_array;
this_val->data.x_struct.parent.data.p_array.elem_index = i;
- this_val->data.x_struct.fields = allocate<ConstExprValue>(2);
+ this_val->data.x_struct.fields = create_const_vals(2);
ConstExprValue *name_field = &this_val->data.x_struct.fields[0];
ConstExprValue *name_array_val = create_const_str_lit(g, &test_fn_entry->symbol_name);
src/ir.cpp
@@ -553,6 +553,7 @@ static T *ir_create_instruction(IrBuilder *irb, Scope *scope, AstNode *source_no
special_instruction->base.source_node = source_node;
special_instruction->base.debug_id = exec_next_debug_id(irb->exec);
special_instruction->base.owner_bb = irb->current_basic_block;
+ special_instruction->base.value.global_refs = allocate<ConstGlobalRefs>(1);
return special_instruction;
}
@@ -3210,7 +3211,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);
+ variable_entry->value = create_const_vals(1);
if (name) {
buf_init_from_buf(&variable_entry->name, name);
@@ -6565,6 +6566,14 @@ static void ir_add_alloca(IrAnalyze *ira, IrInstruction *instruction, TypeTableE
}
}
+static void copy_const_val(ConstExprValue *dest, ConstExprValue *src, bool same_global_refs) {
+ ConstGlobalRefs *global_refs = dest->global_refs;
+ *dest = *src;
+ if (!same_global_refs) {
+ dest->global_refs = global_refs;
+ }
+}
+
static void eval_const_expr_implicit_cast(CastOp cast_op,
ConstExprValue *other_val, TypeTableEntry *other_type,
ConstExprValue *const_val, TypeTableEntry *new_type)
@@ -6576,7 +6585,13 @@ static void eval_const_expr_implicit_cast(CastOp cast_op,
case CastOpNoCast:
zig_unreachable();
case CastOpNoop:
- *const_val = *other_val;
+ {
+ copy_const_val(const_val, other_val, other_val->special == ConstValSpecialStatic);
+ const_val->type = new_type;
+ break;
+ }
+ case CastOpNumLitToConcrete:
+ const_val->data.x_bignum = other_val->data.x_bignum;
const_val->type = new_type;
break;
case CastOpResizeSlice:
@@ -7188,7 +7203,7 @@ static IrInstruction *ir_analyze_widen_or_shorten(IrAnalyze *ira, IrInstruction
}
IrInstruction *result = ir_create_const(&ira->new_irb, source_instr->scope,
source_instr->source_node, wanted_type);
- result->value = *val;
+ result->value.data.x_bignum = val->data.x_bignum;
result->value.type = wanted_type;
return result;
}
@@ -7613,7 +7628,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
(actual_type->id == TypeTableEntryIdNumLitInt &&
wanted_type->id == TypeTableEntryIdInt))
{
- op = CastOpNoop;
+ op = CastOpNumLitToConcrete;
} else if (wanted_type->id == TypeTableEntryIdInt) {
op = CastOpFloatToInt;
} else if (wanted_type->id == TypeTableEntryIdFloat) {
@@ -7741,7 +7756,7 @@ static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruc
if (pointee->special != ConstValSpecialRuntime) {
IrInstruction *result = ir_create_const(&ira->new_irb, source_instruction->scope,
source_instruction->source_node, child_type);
- result->value = *pointee;
+ copy_const_val(&result->value, pointee, ptr->value.data.x_ptr.mut == ConstPtrMutComptimeConst);
return result;
}
}
@@ -8584,7 +8599,7 @@ static TypeTableEntry *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *
result_type = get_pointer_to_type(ira->codegen, child_type, true);
- out_array_val = allocate<ConstExprValue>(1);
+ out_array_val = create_const_vals(1);
out_array_val->special = ConstValSpecialStatic;
out_array_val->type = get_array_type(ira->codegen, child_type, new_len);
out_val->data.x_ptr.special = ConstPtrSpecialBaseArray;
@@ -8592,7 +8607,7 @@ static TypeTableEntry *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *
out_val->data.x_ptr.data.base_array.array_val = out_array_val;
out_val->data.x_ptr.data.base_array.elem_index = 0;
}
- out_array_val->data.x_array.s_none.elements = allocate<ConstExprValue>(new_len);
+ out_array_val->data.x_array.s_none.elements = create_const_vals(new_len);
expand_undef_array(ira->codegen, op1_array_val);
@@ -8648,7 +8663,7 @@ static TypeTableEntry *ir_analyze_array_mult(IrAnalyze *ira, IrInstructionBinOp
ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);
uint64_t new_array_len = array_len.data.x_uint;
- out_val->data.x_array.s_none.elements = allocate<ConstExprValue>(new_array_len);
+ out_val->data.x_array.s_none.elements = create_const_vals(new_array_len);
expand_undef_array(ira->codegen, array_val);
@@ -9139,7 +9154,7 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal
GenericFnTypeId *generic_id = allocate<GenericFnTypeId>(1);
generic_id->fn_entry = fn_entry;
generic_id->param_count = 0;
- generic_id->params = allocate<ConstExprValue>(new_fn_arg_count);
+ generic_id->params = create_const_vals(new_fn_arg_count);
size_t next_proto_i = 0;
if (first_arg_ptr) {
@@ -9451,7 +9466,7 @@ static TypeTableEntry *ir_analyze_dereference(IrAnalyze *ira, IrInstructionUnOp
ConstExprValue *pointee = const_ptr_pointee(ira->codegen, &value->value);
if (pointee->type == child_type) {
ConstExprValue *out_val = ir_build_const_from(ira, &un_op_instruction->base);
- *out_val = *pointee;
+ copy_const_val(out_val, pointee, value->value.data.x_ptr.mut == ConstPtrMutComptimeConst);
return child_type;
}
}
@@ -10118,7 +10133,7 @@ static TypeTableEntry *ir_analyze_decl_ref(IrAnalyze *ira, IrInstruction *source
// TODO instead of allocating this every time, put it in the tld value and we can reference
// the same one every time
- ConstExprValue *const_val = allocate<ConstExprValue>(1);
+ ConstExprValue *const_val = create_const_vals(1);
const_val->special = ConstValSpecialStatic;
const_val->type = fn_entry->type_entry;
const_val->data.x_fn.fn_entry = fn_entry;
@@ -10162,7 +10177,7 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru
}
} else if (container_type->id == TypeTableEntryIdArray) {
if (buf_eql_str(field_name, "len")) {
- ConstExprValue *len_val = allocate<ConstExprValue>(1);
+ ConstExprValue *len_val = create_const_vals(1);
init_const_usize(ira->codegen, len_val, container_type->data.array.len);
TypeTableEntry *usize = ira->codegen->builtin_types.entry_usize;
@@ -10185,7 +10200,7 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru
ConstExprValue *child_val = const_ptr_pointee(ira->codegen, container_ptr_val);
if (buf_eql_str(field_name, "len")) {
- ConstExprValue *len_val = allocate<ConstExprValue>(1);
+ ConstExprValue *len_val = create_const_vals(1);
size_t len = child_val->data.x_arg_tuple.end_index - child_val->data.x_arg_tuple.start_index;
init_const_usize(ira->codegen, len_val, len);
@@ -10258,7 +10273,7 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru
} else if (child_type->id == TypeTableEntryIdPureError) {
auto err_table_entry = ira->codegen->error_table.maybe_get(field_name);
if (err_table_entry) {
- ConstExprValue *const_val = allocate<ConstExprValue>(1);
+ ConstExprValue *const_val = create_const_vals(1);
const_val->special = ConstValSpecialStatic;
const_val->type = child_type;
const_val->data.x_pure_err = err_table_entry->value;
@@ -11346,7 +11361,7 @@ static TypeTableEntry *ir_analyze_instruction_switch_target(IrAnalyze *ira,
case TypeTableEntryIdPureError:
if (pointee_val) {
ConstExprValue *out_val = ir_build_const_from(ira, &switch_target_instruction->base);
- *out_val = *pointee_val;
+ copy_const_val(out_val, pointee_val, true);
out_val->type = target_type;
return target_type;
}
@@ -11583,7 +11598,7 @@ static TypeTableEntry *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstru
ConstExprValue const_val = {};
const_val.special = ConstValSpecialStatic;
const_val.type = container_type;
- const_val.data.x_struct.fields = allocate<ConstExprValue>(actual_field_count);
+ const_val.data.x_struct.fields = create_const_vals(actual_field_count);
for (size_t i = 0; i < instr_field_count; i += 1) {
IrInstructionContainerInitFieldsField *field = &fields[i];
@@ -11624,7 +11639,7 @@ static TypeTableEntry *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstru
if (!field_val)
return ira->codegen->builtin_types.entry_invalid;
- const_val.data.x_struct.fields[field_index] = *field_val;
+ copy_const_val(&const_val.data.x_struct.fields[field_index], field_val, true);
} else {
first_non_const_instruction = casted_field_value;
const_val.special = ConstValSpecialRuntime;
@@ -11698,7 +11713,7 @@ static TypeTableEntry *ir_analyze_instruction_container_init_list(IrAnalyze *ira
ConstExprValue const_val = {};
const_val.special = ConstValSpecialStatic;
const_val.type = fixed_size_array_type;
- const_val.data.x_array.s_none.elements = allocate<ConstExprValue>(elem_count);
+ const_val.data.x_array.s_none.elements = create_const_vals(elem_count);
bool is_comptime = ir_should_inline(ira->new_irb.exec, instruction->base.scope);
@@ -11723,7 +11738,7 @@ static TypeTableEntry *ir_analyze_instruction_container_init_list(IrAnalyze *ira
if (!elem_val)
return ira->codegen->builtin_types.entry_invalid;
- const_val.data.x_array.s_none.elements[i] = *elem_val;
+ copy_const_val(&const_val.data.x_array.s_none.elements[i], elem_val, true);
} else {
first_non_const_instruction = casted_arg;
const_val.special = ConstValSpecialRuntime;
@@ -11950,7 +11965,7 @@ static TypeTableEntry *ir_analyze_instruction_err_name(IrAnalyze *ira, IrInstruc
err->cached_error_name_val = create_const_slice(ira->codegen, array_val, 0, buf_len(&err->name), true);
}
ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);
- *out_val = *err->cached_error_name_val;
+ copy_const_val(out_val, err->cached_error_name_val, true);
return str_type;
}
@@ -12133,7 +12148,7 @@ static TypeTableEntry *ir_analyze_instruction_type_name(IrAnalyze *ira, IrInstru
type_entry->cached_const_name_val = create_const_str_lit(ira->codegen, &type_entry->name);
}
ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);
- *out_val = *type_entry->cached_const_name_val;
+ copy_const_val(out_val, type_entry->cached_const_name_val, true);
return out_val->type;
}
@@ -12809,7 +12824,7 @@ static TypeTableEntry *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstructio
}
ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);
- out_val->data.x_struct.fields = allocate<ConstExprValue>(2);
+ out_val->data.x_struct.fields = create_const_vals(2);
ConstExprValue *ptr_val = &out_val->data.x_struct.fields[slice_ptr_index];
@@ -13370,7 +13385,7 @@ static TypeTableEntry *ir_analyze_instruction_ptr_cast(IrAnalyze *ira, IrInstruc
return ira->codegen->builtin_types.entry_invalid;
ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);
- *out_val = *val;
+ copy_const_val(out_val, val, false);
out_val->type = dest_type;
return dest_type;
}
@@ -13696,7 +13711,7 @@ TypeTableEntry *ir_analyze(CodeGen *codegen, IrExecutable *old_exec, IrExecutabl
ira->new_irb.exec = new_exec;
ira->exec_context.mem_slot_count = ira->old_irb.exec->mem_slot_count;
- ira->exec_context.mem_slot_list = allocate<ConstExprValue>(ira->exec_context.mem_slot_count);
+ ira->exec_context.mem_slot_list = create_const_vals(ira->exec_context.mem_slot_count);
IrBasicBlock *old_entry_bb = ira->old_irb.exec->basic_block_list.at(0);
IrBasicBlock *new_entry_bb = ir_get_new_bb(ira, old_entry_bb, nullptr);
test/cases/eval.zig
@@ -332,3 +332,13 @@ test "compile-time downcast when the bits fit" {
assert(byte == 255);
}
}
+
+const hi1 = "hi";
+const hi2 = hi1;
+test "const global shares pointer with other same one" {
+ assertEqualPtrs(&hi1[0], &hi2[0]);
+ comptime assert(&hi1[0] == &hi2[0]);
+}
+fn assertEqualPtrs(ptr1: &const u8, ptr2: &const u8) {
+ assert(ptr1 == ptr2);
+}
test/cases/var_args.zig
@@ -65,3 +65,17 @@ test "array of var args functions" {
assert(foos[0]());
assert(!foos[1]());
}
+
+
+test "pass array and slice of same array to var args should have same pointers" {
+ const array = "hi";
+ const slice: []const u8 = array;
+ return assertSlicePtrsEql(array, slice);
+}
+
+fn assertSlicePtrsEql(args: ...) {
+ const s1 = ([]const u8)(args[0]);
+ const s2 = args[1];
+ assert(s1.ptr == s2.ptr);
+}
+
test/tests.zig
@@ -591,8 +591,7 @@ pub const CompileErrorContext = struct {
tc.addSourceFile(".tmp_source.zig", source);
comptime var arg_i = 0;
inline while (arg_i < expected_lines.len) : (arg_i += 1) {
- // TODO mem.dupe is because of issue #336
- tc.addExpectedError(%%mem.dupe(self.b.allocator, u8, expected_lines[arg_i]));
+ tc.addExpectedError(expected_lines[arg_i]);
}
return tc;
}
@@ -854,8 +853,7 @@ pub const ParseHContext = struct {
tc.addSourceFile("source.h", source);
comptime var arg_i = 0;
inline while (arg_i < expected_lines.len) : (arg_i += 1) {
- // TODO mem.dupe is because of issue #336
- tc.addExpectedError(%%mem.dupe(self.b.allocator, u8, expected_lines[arg_i]));
+ tc.addExpectedError(expected_lines[arg_i]);
}
return tc;
}