aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMarcio Giaxa <i@mgxm.me>2018-12-23 23:21:59 -0200
committerMarcio Giaxa <i@mgxm.me>2018-12-23 23:21:59 -0200
commit773bf8013391d2b309cfcb50bf9e1c7db25cc3f2 (patch)
treef9afac31b7211b157ca47c8bef022e405b13bed7 /src
parentc26f543970771acba5484553e2c10ec90b3c39eb (diff)
parent280187031a68c577e84c72add037271153d27c62 (diff)
downloadzig-773bf8013391d2b309cfcb50bf9e1c7db25cc3f2.tar.gz
zig-773bf8013391d2b309cfcb50bf9e1c7db25cc3f2.zip
Merge branch 'master' into fbsd2
Diffstat (limited to 'src')
-rw-r--r--src/analyze.cpp55
-rw-r--r--src/ir.cpp65
-rw-r--r--src/translate_c.cpp8
3 files changed, 91 insertions, 37 deletions
diff --git a/src/analyze.cpp b/src/analyze.cpp
index 064cf11cc1..63608e825b 100644
--- a/src/analyze.cpp
+++ b/src/analyze.cpp
@@ -2681,39 +2681,50 @@ static Error resolve_struct_alignment(CodeGen *g, ZigType *struct_type) {
assert(decl_node->type == NodeTypeContainerDecl);
assert(struct_type->di_type);
+ size_t field_count = struct_type->data.structure.src_field_count;
if (struct_type->data.structure.layout == ContainerLayoutPacked) {
struct_type->data.structure.abi_alignment = 1;
- }
-
- size_t field_count = struct_type->data.structure.src_field_count;
- for (size_t i = 0; i < field_count; i += 1) {
- TypeStructField *field = &struct_type->data.structure.fields[i];
-
- // If this assertion trips, look up the call stack. Probably something is
- // calling type_resolve with ResolveStatusAlignmentKnown when it should only
- // be resolving ResolveStatusZeroBitsKnown
- assert(field->type_entry != nullptr);
-
- if (type_is_invalid(field->type_entry)) {
- struct_type->data.structure.resolve_status = ResolveStatusInvalid;
- break;
+ for (size_t i = 0; i < field_count; i += 1) {
+ TypeStructField *field = &struct_type->data.structure.fields[i];
+ if (field->type_entry != nullptr && type_is_invalid(field->type_entry)) {
+ struct_type->data.structure.resolve_status = ResolveStatusInvalid;
+ break;
+ }
}
+ } else for (size_t i = 0; i < field_count; i += 1) {
+ TypeStructField *field = &struct_type->data.structure.fields[i];
+ uint32_t this_field_align;
+
+ // TODO If we have no type_entry for the field, we've already failed to
+ // compile the program correctly. This stage1 compiler needs a deeper
+ // reworking to make this correct, or we can ignore the problem
+ // and make sure it is fixed in stage2. This workaround is for when
+ // there is a false positive of a dependency loop, of alignment depending
+ // on itself. When this false positive happens we assume a pointer-aligned
+ // field, which is usually fine but could be incorrectly over-aligned or
+ // even under-aligned. See https://github.com/ziglang/zig/issues/1512
+ if (field->type_entry == nullptr) {
+ this_field_align = LLVMABIAlignmentOfType(g->target_data_ref, LLVMPointerType(LLVMInt8Type(), 0));
+ } else {
+ if (type_is_invalid(field->type_entry)) {
+ struct_type->data.structure.resolve_status = ResolveStatusInvalid;
+ break;
+ }
- if (!type_has_bits(field->type_entry))
- continue;
+ if (!type_has_bits(field->type_entry))
+ continue;
- // alignment of structs is the alignment of the most-aligned field
- if (struct_type->data.structure.layout != ContainerLayoutPacked) {
if ((err = type_resolve(g, field->type_entry, ResolveStatusAlignmentKnown))) {
struct_type->data.structure.resolve_status = ResolveStatusInvalid;
break;
}
- uint32_t this_field_align = get_abi_alignment(g, field->type_entry);
+ this_field_align = get_abi_alignment(g, field->type_entry);
assert(this_field_align != 0);
- if (this_field_align > struct_type->data.structure.abi_alignment) {
- struct_type->data.structure.abi_alignment = this_field_align;
- }
+ }
+ // alignment of structs is the alignment of the most-aligned field
+ if (this_field_align > struct_type->data.structure.abi_alignment) {
+ struct_type->data.structure.abi_alignment = this_field_align;
}
}
diff --git a/src/ir.cpp b/src/ir.cpp
index 76dd6c6391..83960f2eee 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -159,7 +159,7 @@ static ZigType *ir_resolve_atomic_operand_type(IrAnalyze *ira, IrInstruction *op
static IrInstruction *ir_lval_wrap(IrBuilder *irb, Scope *scope, IrInstruction *value, LVal lval);
static ZigType *adjust_ptr_align(CodeGen *g, ZigType *ptr_type, uint32_t new_align);
static ZigType *adjust_slice_align(CodeGen *g, ZigType *slice_type, uint32_t new_align);
-static void buf_read_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue *val);
+static Error buf_read_value_bytes(IrAnalyze *ira, AstNode *source_node, uint8_t *buf, ConstExprValue *val);
static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue *val);
static Error ir_read_const_ptr(IrAnalyze *ira, AstNode *source_node,
ConstExprValue *out_val, ConstExprValue *ptr_val);
@@ -12495,6 +12495,7 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstruct
case ReqCompTimeNo:
if (casted_init_value->value.special == ConstValSpecialStatic &&
casted_init_value->value.type->id == ZigTypeIdFn &&
+ casted_init_value->value.data.x_ptr.special != ConstPtrSpecialHardCodedAddr &&
casted_init_value->value.data.x_ptr.data.fn.fn_entry->fn_inline == FnInlineAlways)
{
var_class_requires_const = true;
@@ -13724,7 +13725,8 @@ static Error ir_read_const_ptr(IrAnalyze *ira, AstNode *source_node,
Buf buf = BUF_INIT;
buf_resize(&buf, src_size);
buf_write_value_bytes(ira->codegen, (uint8_t*)buf_ptr(&buf), pointee);
- buf_read_value_bytes(ira->codegen, (uint8_t*)buf_ptr(&buf), out_val);
+ if ((err = buf_read_value_bytes(ira, source_node, (uint8_t*)buf_ptr(&buf), out_val)))
+ return err;
return ErrorNone;
}
@@ -13758,7 +13760,8 @@ static Error ir_read_const_ptr(IrAnalyze *ira, AstNode *source_node,
ConstExprValue *elem_val = &array_val->data.x_array.data.s_none.elements[elem_index + i];
buf_write_value_bytes(ira->codegen, (uint8_t*)buf_ptr(&buf) + (i * elem_size), elem_val);
}
- buf_read_value_bytes(ira->codegen, (uint8_t*)buf_ptr(&buf), out_val);
+ if ((err = buf_read_value_bytes(ira, source_node, (uint8_t*)buf_ptr(&buf), out_val)))
+ return err;
return ErrorNone;
}
case ConstPtrSpecialBaseStruct:
@@ -20076,7 +20079,8 @@ static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue
zig_unreachable();
}
-static void buf_read_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue *val) {
+static Error buf_read_value_bytes(IrAnalyze *ira, AstNode *source_node, uint8_t *buf, ConstExprValue *val) {
+ Error err;
assert(val->special == ConstValSpecialStatic);
switch (val->type->id) {
case ZigTypeIdInvalid:
@@ -20093,30 +20097,60 @@ static void buf_read_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue
case ZigTypeIdPromise:
zig_unreachable();
case ZigTypeIdVoid:
- return;
+ return ErrorNone;
case ZigTypeIdBool:
val->data.x_bool = (buf[0] != 0);
- return;
+ return ErrorNone;
case ZigTypeIdInt:
bigint_read_twos_complement(&val->data.x_bigint, buf, val->type->data.integral.bit_count,
- codegen->is_big_endian, val->type->data.integral.is_signed);
- return;
+ ira->codegen->is_big_endian, val->type->data.integral.is_signed);
+ return ErrorNone;
case ZigTypeIdFloat:
- float_read_ieee597(val, buf, codegen->is_big_endian);
- return;
+ float_read_ieee597(val, buf, ira->codegen->is_big_endian);
+ return ErrorNone;
case ZigTypeIdPointer:
{
val->data.x_ptr.special = ConstPtrSpecialHardCodedAddr;
BigInt bn;
- bigint_read_twos_complement(&bn, buf, codegen->builtin_types.entry_usize->data.integral.bit_count,
- codegen->is_big_endian, false);
+ bigint_read_twos_complement(&bn, buf, ira->codegen->builtin_types.entry_usize->data.integral.bit_count,
+ ira->codegen->is_big_endian, false);
val->data.x_ptr.data.hard_coded_addr.addr = bigint_as_unsigned(&bn);
- return;
+ return ErrorNone;
}
case ZigTypeIdArray:
zig_panic("TODO buf_read_value_bytes array type");
case ZigTypeIdStruct:
- zig_panic("TODO buf_read_value_bytes struct type");
+ switch (val->type->data.structure.layout) {
+ case ContainerLayoutAuto: {
+ ErrorMsg *msg = ir_add_error_node(ira, source_node,
+ buf_sprintf("non-extern, non-packed struct '%s' cannot have its bytes reinterpreted",
+ buf_ptr(&val->type->name)));
+ add_error_note(ira->codegen, msg, val->type->data.structure.decl_node,
+ buf_sprintf("declared here"));
+ return ErrorSemanticAnalyzeFail;
+ }
+ case ContainerLayoutExtern: {
+ size_t src_field_count = val->type->data.structure.src_field_count;
+ val->data.x_struct.fields = create_const_vals(src_field_count);
+ for (size_t field_i = 0; field_i < src_field_count; field_i += 1) {
+ ConstExprValue *field_val = &val->data.x_struct.fields[field_i];
+ field_val->special = ConstValSpecialStatic;
+ TypeStructField *type_field = &val->type->data.structure.fields[field_i];
+ field_val->type = type_field->type_entry;
+ if (type_field->gen_index == SIZE_MAX)
+ continue;
+ size_t offset = LLVMOffsetOfElement(ira->codegen->target_data_ref, val->type->type_ref,
+ type_field->gen_index);
+ uint8_t *new_buf = buf + offset;
+ if ((err = buf_read_value_bytes(ira, source_node, new_buf, field_val)))
+ return err;
+ }
+ return ErrorNone;
+ }
+ case ContainerLayoutPacked:
+ zig_panic("TODO buf_read_value_bytes packed struct");
+ }
+ zig_unreachable();
case ZigTypeIdOptional:
zig_panic("TODO buf_read_value_bytes maybe type");
case ZigTypeIdErrorUnion:
@@ -20219,7 +20253,8 @@ static IrInstruction *ir_analyze_instruction_bit_cast(IrAnalyze *ira, IrInstruct
IrInstruction *result = ir_const(ira, &instruction->base, dest_type);
uint8_t *buf = allocate_nonzero<uint8_t>(src_size_bytes);
buf_write_value_bytes(ira->codegen, buf, val);
- buf_read_value_bytes(ira->codegen, buf, &result->value);
+ if ((err = buf_read_value_bytes(ira, instruction->base.source_node, buf, &result->value)))
+ return ira->codegen->invalid_instruction;
return result;
}
diff --git a/src/translate_c.cpp b/src/translate_c.cpp
index 10f2124eb6..f6bc9cd683 100644
--- a/src/translate_c.cpp
+++ b/src/translate_c.cpp
@@ -4776,6 +4776,14 @@ Error parse_h_file(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, const
clang_argv.append(target_file);
+ if (codegen->verbose_cimport) {
+ fprintf(stderr, "clang");
+ for (size_t i = 0; i < clang_argv.length; i += 1) {
+ fprintf(stderr, " %s", clang_argv.at(i));
+ }
+ fprintf(stderr, "\n");
+ }
+
// to make the [start...end] argument work
clang_argv.append(nullptr);