mirror of
https://github.com/ziglang/zig.git
synced 2026-02-18 23:39:17 +00:00
parent
37318bf151
commit
32b37e695a
@ -5432,7 +5432,7 @@ bool fn_eval_eql(Scope *a, Scope *b) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Whether the type has bits at runtime.
|
||||
// Deprecated. Use type_has_bits2.
|
||||
bool type_has_bits(ZigType *type_entry) {
|
||||
assert(type_entry != nullptr);
|
||||
assert(!type_is_invalid(type_entry));
|
||||
@ -5440,6 +5440,27 @@ bool type_has_bits(ZigType *type_entry) {
|
||||
return type_entry->abi_size != 0;
|
||||
}
|
||||
|
||||
// Whether the type has bits at runtime.
|
||||
Error type_has_bits2(CodeGen *g, ZigType *type_entry, bool *result) {
|
||||
Error err;
|
||||
|
||||
if (type_is_invalid(type_entry))
|
||||
return ErrorSemanticAnalyzeFail;
|
||||
|
||||
if (type_entry->id == ZigTypeIdStruct &&
|
||||
type_entry->data.structure.resolve_status == ResolveStatusBeingInferred)
|
||||
{
|
||||
*result = true;
|
||||
return ErrorNone;
|
||||
}
|
||||
|
||||
if ((err = type_resolve(g, type_entry, ResolveStatusZeroBitsKnown)))
|
||||
return err;
|
||||
|
||||
*result = type_entry->abi_size != 0;
|
||||
return ErrorNone;
|
||||
}
|
||||
|
||||
// Whether you can infer the value based solely on the type.
|
||||
OnePossibleValue type_has_one_possible_value(CodeGen *g, ZigType *type_entry) {
|
||||
assert(type_entry != nullptr);
|
||||
|
||||
@ -46,6 +46,8 @@ ZigType *get_any_frame_type(CodeGen *g, ZigType *result_type);
|
||||
bool handle_is_ptr(ZigType *type_entry);
|
||||
|
||||
bool type_has_bits(ZigType *type_entry);
|
||||
Error type_has_bits2(CodeGen *g, ZigType *type_entry, bool *result);
|
||||
|
||||
Error type_allowed_in_extern(CodeGen *g, ZigType *type_entry, bool *result);
|
||||
bool ptr_allows_addr_zero(ZigType *ptr_type);
|
||||
bool type_is_nonnull_ptr(ZigType *type);
|
||||
|
||||
@ -3622,9 +3622,14 @@ static void gen_undef_init(CodeGen *g, uint32_t ptr_align_bytes, ZigType *value_
|
||||
}
|
||||
|
||||
static LLVMValueRef ir_render_store_ptr(CodeGen *g, IrExecutable *executable, IrInstructionStorePtr *instruction) {
|
||||
Error err;
|
||||
|
||||
ZigType *ptr_type = instruction->ptr->value.type;
|
||||
assert(ptr_type->id == ZigTypeIdPointer);
|
||||
if (!type_has_bits(ptr_type))
|
||||
bool ptr_type_has_bits;
|
||||
if ((err = type_has_bits2(g, ptr_type, &ptr_type_has_bits)))
|
||||
codegen_report_errors_and_exit(g);
|
||||
if (!ptr_type_has_bits)
|
||||
return nullptr;
|
||||
if (instruction->ptr->ref_count == 0) {
|
||||
// In this case, this StorePtr instruction should be elided. Something happened like this:
|
||||
|
||||
17
src/ir.cpp
17
src/ir.cpp
@ -15513,15 +15513,16 @@ static IrInstruction *ir_analyze_alloca(IrAnalyze *ira, IrInstruction *source_in
|
||||
result->base.value.data.x_ptr.mut = force_comptime ? ConstPtrMutComptimeVar : ConstPtrMutInfer;
|
||||
result->base.value.data.x_ptr.data.ref.pointee = pointee;
|
||||
|
||||
if ((err = type_resolve(ira->codegen, var_type, ResolveStatusZeroBitsKnown)))
|
||||
bool var_type_has_bits;
|
||||
if ((err = type_has_bits2(ira->codegen, var_type, &var_type_has_bits)))
|
||||
return ira->codegen->invalid_instruction;
|
||||
if (align != 0) {
|
||||
if ((err = type_resolve(ira->codegen, var_type, ResolveStatusAlignmentKnown)))
|
||||
return ira->codegen->invalid_instruction;
|
||||
if (!type_has_bits(var_type)) {
|
||||
ir_add_error(ira, source_inst,
|
||||
buf_sprintf("variable '%s' of zero-bit type '%s' has no in-memory representation, it cannot be aligned",
|
||||
name_hint, buf_ptr(&var_type->name)));
|
||||
if (!var_type_has_bits) {
|
||||
ir_add_error(ira, source_inst,
|
||||
buf_sprintf("variable '%s' of zero-bit type '%s' has no in-memory representation, it cannot be aligned",
|
||||
name_hint, buf_ptr(&var_type->name)));
|
||||
return ira->codegen->invalid_instruction;
|
||||
}
|
||||
}
|
||||
@ -22138,15 +22139,15 @@ static IrInstruction *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstruct
|
||||
}
|
||||
for (size_t i = 0; i < errors_len; i += 1) {
|
||||
Stage2ErrorMsg *clang_err = &errors_ptr[i];
|
||||
// Clang can emit "too many errors, stopping now", in which case `source` and `filename_ptr` are null
|
||||
if (clang_err->source && clang_err->filename_ptr) {
|
||||
// Clang can emit "too many errors, stopping now", in which case `source` and `filename_ptr` are null
|
||||
if (clang_err->source && clang_err->filename_ptr) {
|
||||
ErrorMsg *err_msg = err_msg_create_with_offset(
|
||||
clang_err->filename_ptr ?
|
||||
buf_create_from_mem(clang_err->filename_ptr, clang_err->filename_len) : buf_alloc(),
|
||||
clang_err->line, clang_err->column, clang_err->offset, clang_err->source,
|
||||
buf_create_from_mem(clang_err->msg_ptr, clang_err->msg_len));
|
||||
err_msg_add_note(parent_err_msg, err_msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ira->codegen->invalid_instruction;
|
||||
|
||||
@ -755,7 +755,7 @@ test "fully anonymous struct" {
|
||||
test "fully anonymous list literal" {
|
||||
const S = struct {
|
||||
fn doTheTest() void {
|
||||
dump(.{ @as(u32, 1234), @as(f64, 12.34), true, "hi"});
|
||||
dump(.{ @as(u32, 1234), @as(f64, 12.34), true, "hi" });
|
||||
}
|
||||
fn dump(args: var) void {
|
||||
expect(args.@"0" == 1234);
|
||||
@ -768,3 +768,12 @@ test "fully anonymous list literal" {
|
||||
S.doTheTest();
|
||||
comptime S.doTheTest();
|
||||
}
|
||||
|
||||
test "anonymous struct literal assigned to variable" {
|
||||
var vec = .{ @as(i32, 22), @as(i32, 55), @as(i32, 99) };
|
||||
expect(vec.@"0" == 22);
|
||||
expect(vec.@"1" == 55);
|
||||
expect(vec.@"2" == 99);
|
||||
vec.@"1" += 1;
|
||||
expect(vec.@"1" == 56);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user