Commit 7f7823e23c
Changed files (5)
test
cases
src/all_types.hpp
@@ -144,6 +144,8 @@ enum ConstPtrSpecial {
// This means that the pointer represents memory of assigning to _.
// That is, storing discards the data, and loading is invalid.
ConstPtrSpecialDiscard,
+ // This is actually a function.
+ ConstPtrSpecialFunction,
};
enum ConstPtrMut {
@@ -180,6 +182,9 @@ struct ConstPtrValue {
struct {
uint64_t addr;
} hard_coded_addr;
+ struct {
+ FnTableEntry *fn_entry;
+ } fn;
} data;
};
@@ -222,10 +227,6 @@ enum RuntimeHintPtr {
RuntimeHintPtrNonStack,
};
-struct ConstFn {
- FnTableEntry *fn_entry;
-};
-
struct ConstGlobalRefs {
LLVMValueRef llvm_value;
LLVMValueRef llvm_global;
@@ -244,7 +245,6 @@ struct ConstExprValue {
double x_f64;
float128_t x_f128;
bool x_bool;
- ConstFn x_fn;
ConstBoundFnValue x_bound_fn;
TypeTableEntry *x_type;
ConstExprValue *x_maybe;
src/analyze.cpp
@@ -4447,6 +4447,10 @@ static uint32_t hash_const_val(ConstExprValue *const_val) {
case TypeTableEntryIdArgTuple:
return (uint32_t)const_val->data.x_arg_tuple.start_index * (uint32_t)281907309 +
(uint32_t)const_val->data.x_arg_tuple.end_index * (uint32_t)2290442768;
+ case TypeTableEntryIdFn:
+ assert(const_val->data.x_ptr.mut == ConstPtrMutComptimeConst);
+ assert(const_val->data.x_ptr.special == ConstPtrSpecialFunction);
+ return 3677364617 ^ hash_ptr(const_val->data.x_ptr.data.fn.fn_entry);
case TypeTableEntryIdPointer:
{
uint32_t hash_val = 0;
@@ -4486,6 +4490,10 @@ static uint32_t hash_const_val(ConstExprValue *const_val) {
case ConstPtrSpecialDiscard:
hash_val += 2010123162;
return hash_val;
+ case ConstPtrSpecialFunction:
+ hash_val += (uint32_t)2590901619;
+ hash_val += hash_ptr(const_val->data.x_ptr.data.fn.fn_entry);
+ return hash_val;
}
zig_unreachable();
}
@@ -4517,8 +4525,6 @@ static uint32_t hash_const_val(ConstExprValue *const_val) {
case TypeTableEntryIdErrorSet:
assert(const_val->data.x_err_set != nullptr);
return const_val->data.x_err_set->value ^ 2630160122;
- case TypeTableEntryIdFn:
- return 4133894920 ^ hash_ptr(const_val->data.x_fn.fn_entry);
case TypeTableEntryIdNamespace:
return hash_ptr(const_val->data.x_import);
case TypeTableEntryIdBlock:
@@ -5150,8 +5156,6 @@ bool const_values_equal(ConstExprValue *a, ConstExprValue *b) {
return true;
case TypeTableEntryIdErrorSet:
return a->data.x_err_set->value == b->data.x_err_set->value;
- case TypeTableEntryIdFn:
- return a->data.x_fn.fn_entry == b->data.x_fn.fn_entry;
case TypeTableEntryIdBool:
return a->data.x_bool == b->data.x_bool;
case TypeTableEntryIdFloat:
@@ -5172,6 +5176,7 @@ bool const_values_equal(ConstExprValue *a, ConstExprValue *b) {
case TypeTableEntryIdNumLitInt:
return bigint_cmp(&a->data.x_bigint, &b->data.x_bigint) == CmpEQ;
case TypeTableEntryIdPointer:
+ case TypeTableEntryIdFn:
if (a->data.x_ptr.special != b->data.x_ptr.special)
return false;
if (a->data.x_ptr.mut != b->data.x_ptr.mut)
@@ -5211,6 +5216,8 @@ bool const_values_equal(ConstExprValue *a, ConstExprValue *b) {
return true;
case ConstPtrSpecialDiscard:
return true;
+ case ConstPtrSpecialFunction:
+ return a->data.x_ptr.data.fn.fn_entry == b->data.x_ptr.data.fn.fn_entry;
}
zig_unreachable();
case TypeTableEntryIdArray:
@@ -5371,6 +5378,14 @@ void render_const_value(CodeGen *g, Buf *buf, ConstExprValue *const_val) {
buf_appendf(buf, "%s", value);
return;
}
+ case TypeTableEntryIdFn:
+ {
+ assert(const_val->data.x_ptr.mut == ConstPtrMutComptimeConst);
+ assert(const_val->data.x_ptr.special == ConstPtrSpecialFunction);
+ FnTableEntry *fn_entry = const_val->data.x_ptr.data.fn.fn_entry;
+ buf_appendf(buf, "%s", buf_ptr(&fn_entry->symbol_name));
+ return;
+ }
case TypeTableEntryIdPointer:
switch (const_val->data.x_ptr.special) {
case ConstPtrSpecialInvalid:
@@ -5396,14 +5411,14 @@ void render_const_value(CodeGen *g, Buf *buf, ConstExprValue *const_val) {
case ConstPtrSpecialDiscard:
buf_append_str(buf, "&_");
return;
+ case ConstPtrSpecialFunction:
+ {
+ FnTableEntry *fn_entry = const_val->data.x_ptr.data.fn.fn_entry;
+ buf_appendf(buf, "@ptrCast(%s, %s)", buf_ptr(&const_val->type->name), buf_ptr(&fn_entry->symbol_name));
+ return;
+ }
}
zig_unreachable();
- case TypeTableEntryIdFn:
- {
- FnTableEntry *fn_entry = const_val->data.x_fn.fn_entry;
- buf_appendf(buf, "%s", buf_ptr(&fn_entry->symbol_name));
- return;
- }
case TypeTableEntryIdBlock:
{
AstNode *node = const_val->data.x_block->source_node;
src/codegen.cpp
@@ -4840,7 +4840,9 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val, const c
case TypeTableEntryIdEnum:
return bigint_to_llvm_const(type_entry->type_ref, &const_val->data.x_enum_tag);
case TypeTableEntryIdFn:
- return fn_llvm_value(g, const_val->data.x_fn.fn_entry);
+ assert(const_val->data.x_ptr.special == ConstPtrSpecialFunction);
+ assert(const_val->data.x_ptr.mut == ConstPtrMutComptimeConst);
+ return fn_llvm_value(g, const_val->data.x_ptr.data.fn.fn_entry);
case TypeTableEntryIdPointer:
{
render_const_val_global(g, const_val, name);
@@ -4909,6 +4911,8 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val, const c
render_const_val_global(g, const_val, "");
return const_val->global_refs->llvm_value;
}
+ case ConstPtrSpecialFunction:
+ return LLVMConstBitCast(fn_llvm_value(g, const_val->data.x_ptr.data.fn.fn_entry), const_val->type->type_ref);
}
}
zig_unreachable();
@@ -6313,7 +6317,9 @@ static void create_test_compile_var_and_add_test_runner(CodeGen *g) {
ConstExprValue *fn_field = &this_val->data.x_struct.fields[1];
fn_field->type = fn_type;
fn_field->special = ConstValSpecialStatic;
- fn_field->data.x_fn.fn_entry = test_fn_entry;
+ fn_field->data.x_ptr.special = ConstPtrSpecialFunction;
+ fn_field->data.x_ptr.mut = ConstPtrMutComptimeConst;
+ fn_field->data.x_ptr.data.fn.fn_entry = test_fn_entry;
}
ConstExprValue *test_fn_slice = create_const_slice(g, test_fn_array, 0, g->test_fns.length, true);
src/ir.cpp
@@ -130,6 +130,8 @@ ConstExprValue *const_ptr_pointee(CodeGen *g, ConstExprValue *const_val) {
zig_unreachable();
case ConstPtrSpecialDiscard:
zig_unreachable();
+ case ConstPtrSpecialFunction:
+ zig_unreachable();
}
zig_unreachable();
}
@@ -875,7 +877,9 @@ static IrInstruction *ir_create_const_fn(IrBuilder *irb, Scope *scope, AstNode *
IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(irb, scope, source_node);
const_instruction->base.value.type = fn_entry->type_entry;
const_instruction->base.value.special = ConstValSpecialStatic;
- const_instruction->base.value.data.x_fn.fn_entry = fn_entry;
+ const_instruction->base.value.data.x_ptr.data.fn.fn_entry = fn_entry;
+ const_instruction->base.value.data.x_ptr.mut = ConstPtrMutComptimeConst;
+ const_instruction->base.value.data.x_ptr.special = ConstPtrSpecialFunction;
return &const_instruction->base;
}
@@ -8723,7 +8727,8 @@ static FnTableEntry *ir_resolve_fn(IrAnalyze *ira, IrInstruction *fn_value) {
if (!const_val)
return nullptr;
- return const_val->data.x_fn.fn_entry;
+ assert(const_val->data.x_ptr.special == ConstPtrSpecialFunction);
+ return const_val->data.x_ptr.data.fn.fn_entry;
}
static IrInstruction *ir_analyze_maybe_wrap(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value, TypeTableEntry *wanted_type) {
@@ -11311,7 +11316,8 @@ static TypeTableEntry *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructi
case TypeTableEntryIdUnreachable:
zig_unreachable();
case TypeTableEntryIdFn: {
- FnTableEntry *fn_entry = target->value.data.x_fn.fn_entry;
+ assert(target->value.data.x_ptr.special == ConstPtrSpecialFunction);
+ FnTableEntry *fn_entry = target->value.data.x_ptr.data.fn.fn_entry;
CallingConvention cc = fn_entry->type_entry->data.fn.fn_type_id.cc;
switch (cc) {
case CallingConventionUnspecified: {
@@ -12852,6 +12858,8 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc
zig_panic("TODO elem ptr on a const inner struct");
case ConstPtrSpecialHardCodedAddr:
zig_unreachable();
+ case ConstPtrSpecialFunction:
+ zig_panic("TODO element ptr of a function casted to a ptr");
}
if (new_index >= mem_size) {
ir_add_error_node(ira, elem_ptr_instruction->base.source_node,
@@ -12901,6 +12909,8 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc
zig_panic("TODO elem ptr on a slice backed by const inner struct");
case ConstPtrSpecialHardCodedAddr:
zig_unreachable();
+ case ConstPtrSpecialFunction:
+ zig_panic("TODO elem ptr on a slice that was ptrcast from a function");
}
return return_type;
} else if (array_type->id == TypeTableEntryIdArray) {
@@ -13101,7 +13111,9 @@ static TypeTableEntry *ir_analyze_decl_ref(IrAnalyze *ira, IrInstruction *source
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;
+ const_val->data.x_ptr.data.fn.fn_entry = fn_entry;
+ const_val->data.x_ptr.special = ConstPtrSpecialFunction;
+ const_val->data.x_ptr.mut = ConstPtrMutComptimeConst;
if (tld_fn->extern_lib_name != nullptr) {
add_link_lib_symbol(ira, tld_fn->extern_lib_name, &fn_entry->symbol_name, source_instruction->source_node);
@@ -13771,7 +13783,8 @@ static TypeTableEntry *ir_analyze_instruction_set_float_mode(IrAnalyze *ira,
fast_math_off_ptr = &block_scope->fast_math_off;
fast_math_set_node_ptr = &block_scope->fast_math_set_node;
} else if (target_type->id == TypeTableEntryIdFn) {
- FnTableEntry *target_fn = target_val->data.x_fn.fn_entry;
+ assert(target_val->data.x_ptr.special == ConstPtrSpecialFunction);
+ FnTableEntry *target_fn = target_val->data.x_ptr.data.fn.fn_entry;
assert(target_fn->def_scope);
fast_math_off_ptr = &target_fn->def_scope->fast_math_off;
fast_math_set_node_ptr = &target_fn->def_scope->fast_math_set_node;
@@ -15673,6 +15686,8 @@ static TypeTableEntry *ir_analyze_instruction_memset(IrAnalyze *ira, IrInstructi
zig_panic("TODO memset on const inner struct");
case ConstPtrSpecialHardCodedAddr:
zig_unreachable();
+ case ConstPtrSpecialFunction:
+ zig_panic("TODO memset on ptr cast from function");
}
size_t count = bigint_as_unsigned(&casted_count->value.data.x_bigint);
@@ -15769,6 +15784,8 @@ static TypeTableEntry *ir_analyze_instruction_memcpy(IrAnalyze *ira, IrInstructi
zig_panic("TODO memcpy on const inner struct");
case ConstPtrSpecialHardCodedAddr:
zig_unreachable();
+ case ConstPtrSpecialFunction:
+ zig_panic("TODO memcpy on ptr cast from function");
}
if (dest_start + count > dest_end) {
@@ -15803,6 +15820,8 @@ static TypeTableEntry *ir_analyze_instruction_memcpy(IrAnalyze *ira, IrInstructi
zig_panic("TODO memcpy on const inner struct");
case ConstPtrSpecialHardCodedAddr:
zig_unreachable();
+ case ConstPtrSpecialFunction:
+ zig_panic("TODO memcpy on ptr cast from function");
}
if (src_start + count > src_end) {
@@ -15925,6 +15944,8 @@ static TypeTableEntry *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstructio
abs_offset = 0;
rel_end = SIZE_MAX;
break;
+ case ConstPtrSpecialFunction:
+ zig_panic("TODO slice of ptr cast from function");
}
} else if (is_slice(array_type)) {
ConstExprValue *slice_ptr = const_ptr_pointee(ira->codegen, &ptr_ptr->value);
@@ -15952,6 +15973,8 @@ static TypeTableEntry *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstructio
abs_offset = 0;
rel_end = bigint_as_unsigned(&len_val->data.x_bigint);
break;
+ case ConstPtrSpecialFunction:
+ zig_panic("TODO slice of slice cast from function");
}
} else {
zig_unreachable();
@@ -16021,6 +16044,9 @@ static TypeTableEntry *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstructio
parent_ptr->type->data.pointer.child_type,
parent_ptr->data.x_ptr.data.hard_coded_addr.addr + start_scalar,
slice_is_const(return_type));
+ break;
+ case ConstPtrSpecialFunction:
+ zig_panic("TODO");
}
ConstExprValue *len_val = &out_val->data.x_struct.fields[slice_len_index];
test/cases/misc.zig
@@ -660,3 +660,10 @@ test "slicing zero length array" {
assert(mem.eql(u8, s1, ""));
assert(mem.eql(u32, s2, []u32{}));
}
+
+
+const addr1 = @ptrCast(&const u8, emptyFn);
+test "comptime cast fn to ptr" {
+ const addr2 = @ptrCast(&const u8, emptyFn);
+ comptime assert(addr1 == addr2);
+}