From d33766e6c7289b79256b2e50d0dc2344729ff710 Mon Sep 17 00:00:00 2001 From: Timon Kruiper Date: Wed, 1 Apr 2020 20:42:43 +0200 Subject: [PATCH] Make sure that ZigTypeVector and ZigTypeArray have the same memory layout Throughout the stage1 code it is assumed that these have the same layout, but that was not the case. This caused an issue on 32-bit hardware. --- src/all_types.hpp | 8 +++++++- src/analyze.cpp | 1 + src/codegen.cpp | 2 +- src/ir.cpp | 2 +- 4 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/all_types.hpp b/src/all_types.hpp index f51a9c0572e20fce408f90ee7817005fbd1f7fd0..c0d728124be32c6ce1aa496c3e864b79401a4863 100644 --- a/src/all_types.hpp +++ b/src/all_types.hpp @@ -1324,6 +1324,7 @@ struct ZigTypeFloat { size_t bit_count; }; +// Needs to have the same memory layout as ZigTypeVector struct ZigTypeArray { ZigType *child_type; uint64_t len; @@ -1512,12 +1513,17 @@ struct ZigTypeBoundFn { ZigType *fn_type; }; +// Needs to have the same memory layout as ZigTypeArray struct ZigTypeVector { // The type must be a pointer, integer, bool, or float ZigType *elem_type; - uint32_t len; + uint64_t len; + size_t padding; }; +// A lot of code is relying on ZigTypeArray and ZigTypeVector having the same layout/size +static_assert(sizeof(ZigTypeVector) == sizeof(ZigTypeArray), "Size of ZigTypeVector and ZigTypeArray do not match!"); + enum ZigTypeId { ZigTypeIdInvalid, ZigTypeIdMetaType, diff --git a/src/analyze.cpp b/src/analyze.cpp index df7bcdf9de6417b4162db134b7436fedb6194d0e..45983e5d389a79a14e50c0ce47a94066f0f289c9 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -5156,6 +5156,7 @@ ZigType *get_vector_type(CodeGen *g, uint32_t len, ZigType *elem_type) { } entry->data.vector.len = len; entry->data.vector.elem_type = elem_type; + entry->data.vector.padding = 0; buf_resize(&entry->name, 0); buf_appendf(&entry->name, "@Vector(%u, %s)", len, buf_ptr(&elem_type->name)); diff --git a/src/codegen.cpp b/src/codegen.cpp index d36e398bf7ef5119abd8558f9f69657b5c181393..088b3779a99ba9790d4738549dc613eb26e065fc 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -714,7 +714,7 @@ static LLVMValueRef get_arithmetic_overflow_fn(CodeGen *g, ZigType *operand_type }; if (operand_type->id == ZigTypeIdVector) { - sprintf(fn_name, "llvm.%s.with.overflow.v%" PRIu32 "i%" PRIu32, signed_str, + sprintf(fn_name, "llvm.%s.with.overflow.v%" PRIu64 "i%" PRIu32, signed_str, operand_type->data.vector.len, int_type->data.integral.bit_count); LLVMTypeRef return_elem_types[] = { diff --git a/src/ir.cpp b/src/ir.cpp index 215dac5946c4528cd0192fdc96196c157c57e93d..41c4a3b58c390d744b299e28a3d8ff9b48922d27 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -15953,7 +15953,7 @@ static IrInstGen *ir_analyze_bin_op_cmp_numeric(IrAnalyze *ira, IrInst *source_i if (op1->value->type->id == ZigTypeIdVector && op2->value->type->id == ZigTypeIdVector) { if (op1->value->type->data.vector.len != op2->value->type->data.vector.len) { ir_add_error(ira, source_instr, - buf_sprintf("vector length mismatch: %" PRIu32 " and %" PRIu32, + buf_sprintf("vector length mismatch: %" PRIu64 " and %" PRIu64, op1->value->type->data.vector.len, op2->value->type->data.vector.len)); return ira->codegen->invalid_inst_gen; } -- 2.54.0