aboutsummaryrefslogtreecommitdiff
path: root/src/analyze.cpp
diff options
context:
space:
mode:
authorAndrew Kelley <superjoe30@gmail.com>2018-12-23 17:04:26 -0500
committerAndrew Kelley <superjoe30@gmail.com>2018-12-23 17:04:26 -0500
commitc00216701c64269a2395e84f3ccff99d6fb89ffc (patch)
tree9fa071b9e96f9eadc5069b71634b11fc13b00839 /src/analyze.cpp
parentc21884e1d64e4193e03be4f3064917a26b34b142 (diff)
parent45081c1e9cc28757cb563c77553631f7a92b29d8 (diff)
downloadzig-c00216701c64269a2395e84f3ccff99d6fb89ffc.tar.gz
zig-c00216701c64269a2395e84f3ccff99d6fb89ffc.zip
Merge remote-tracking branch 'origin/master' into llvm8
Diffstat (limited to 'src/analyze.cpp')
-rw-r--r--src/analyze.cpp158
1 files changed, 97 insertions, 61 deletions
diff --git a/src/analyze.cpp b/src/analyze.cpp
index bc9789fca8..9c24f3cc8d 100644
--- a/src/analyze.cpp
+++ b/src/analyze.cpp
@@ -401,7 +401,8 @@ ZigType *get_promise_type(CodeGen *g, ZigType *result_type) {
}
ZigType *get_pointer_to_type_extra(CodeGen *g, ZigType *child_type, bool is_const,
- bool is_volatile, PtrLen ptr_len, uint32_t byte_alignment, uint32_t bit_offset_in_host, uint32_t host_int_bytes)
+ bool is_volatile, PtrLen ptr_len, uint32_t byte_alignment,
+ uint32_t bit_offset_in_host, uint32_t host_int_bytes)
{
assert(!type_is_invalid(child_type));
assert(ptr_len == PtrLenSingle || child_type->id != ZigTypeIdOpaque);
@@ -1059,7 +1060,7 @@ bool want_first_arg_sret(CodeGen *g, FnTypeId *fn_type_id) {
}
zig_panic("TODO implement C ABI for x86_64 return types. type '%s'\nSee https://github.com/ziglang/zig/issues/1481",
buf_ptr(&fn_type_id->return_type->name));
- } else if (g->zig_target.arch.arch == ZigLLVM_arm || g->zig_target.arch.arch == ZigLLVM_armeb) {
+ } else if (target_is_arm(&g->zig_target)) {
return type_size(g, fn_type_id->return_type) > 16;
}
zig_panic("TODO implement C ABI for this architecture. See https://github.com/ziglang/zig/issues/1481");
@@ -1619,13 +1620,16 @@ static ZigType *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *child_sc
case ZigTypeIdUnion:
case ZigTypeIdFn:
case ZigTypeIdPromise:
- if ((err = type_resolve(g, type_entry, ResolveStatusZeroBitsKnown)))
- return g->builtin_types.entry_invalid;
- if (type_requires_comptime(type_entry)) {
- add_node_error(g, param_node->data.param_decl.type,
- buf_sprintf("parameter of type '%s' must be declared comptime",
- buf_ptr(&type_entry->name)));
- return g->builtin_types.entry_invalid;
+ switch (type_requires_comptime(g, type_entry)) {
+ case ReqCompTimeNo:
+ break;
+ case ReqCompTimeYes:
+ add_node_error(g, param_node->data.param_decl.type,
+ buf_sprintf("parameter of type '%s' must be declared comptime",
+ buf_ptr(&type_entry->name)));
+ return g->builtin_types.entry_invalid;
+ case ReqCompTimeInvalid:
+ return g->builtin_types.entry_invalid;
}
break;
}
@@ -1711,10 +1715,13 @@ static ZigType *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *child_sc
case ZigTypeIdUnion:
case ZigTypeIdFn:
case ZigTypeIdPromise:
- if ((err = type_resolve(g, fn_type_id.return_type, ResolveStatusZeroBitsKnown)))
- return g->builtin_types.entry_invalid;
- if (type_requires_comptime(fn_type_id.return_type)) {
- return get_generic_fn_type(g, &fn_type_id);
+ switch (type_requires_comptime(g, fn_type_id.return_type)) {
+ case ReqCompTimeInvalid:
+ return g->builtin_types.entry_invalid;
+ case ReqCompTimeYes:
+ return get_generic_fn_type(g, &fn_type_id);
+ case ReqCompTimeNo:
+ break;
}
break;
}
@@ -2560,8 +2567,6 @@ static Error resolve_enum_zero_bits(CodeGen *g, ZigType *enum_type) {
static Error resolve_struct_zero_bits(CodeGen *g, ZigType *struct_type) {
assert(struct_type->id == ZigTypeIdStruct);
- Error err;
-
if (struct_type->data.structure.resolve_status == ResolveStatusInvalid)
return ErrorSemanticAnalyzeFail;
if (struct_type->data.structure.resolve_status >= ResolveStatusZeroBitsKnown)
@@ -2619,13 +2624,15 @@ static Error resolve_struct_zero_bits(CodeGen *g, ZigType *struct_type) {
buf_sprintf("enums, not structs, support field assignment"));
}
- if ((err = type_resolve(g, field_type, ResolveStatusZeroBitsKnown))) {
- struct_type->data.structure.resolve_status = ResolveStatusInvalid;
- continue;
- }
-
- if (type_requires_comptime(field_type)) {
- struct_type->data.structure.requires_comptime = true;
+ switch (type_requires_comptime(g, field_type)) {
+ case ReqCompTimeYes:
+ struct_type->data.structure.requires_comptime = true;
+ break;
+ case ReqCompTimeInvalid:
+ struct_type->data.structure.resolve_status = ResolveStatusInvalid;
+ continue;
+ case ReqCompTimeNo:
+ break;
}
if (!type_has_bits(field_type))
@@ -2674,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;
}
}
@@ -2890,11 +2908,17 @@ static Error resolve_union_zero_bits(CodeGen *g, ZigType *union_type) {
}
union_field->type_entry = field_type;
- if (type_requires_comptime(field_type)) {
- union_type->data.unionation.requires_comptime = true;
+ switch (type_requires_comptime(g, field_type)) {
+ case ReqCompTimeInvalid:
+ union_type->data.unionation.is_invalid = true;
+ continue;
+ case ReqCompTimeYes:
+ union_type->data.unionation.requires_comptime = true;
+ break;
+ case ReqCompTimeNo:
+ break;
}
-
if (field_node->data.struct_field.value != nullptr && !decl_node->data.container_decl.auto_enum) {
ErrorMsg *msg = add_node_error(g, field_node->data.struct_field.value,
buf_sprintf("non-enum union field assignment"));
@@ -4579,7 +4603,10 @@ void find_libc_include_path(CodeGen *g) {
fprintf(stderr, "Unable to determine libc include path. --libc-include-dir");
exit(1);
}
- } else if (g->zig_target.os == OsLinux || g->zig_target.os == OsMacOSX) {
+ } else if (g->zig_target.os == OsLinux ||
+ g->zig_target.os == OsMacOSX ||
+ g->zig_target.os == OsFreeBSD)
+ {
g->libc_include_dir = get_posix_libc_include_path();
} else {
fprintf(stderr, "Unable to determine libc include path.\n"
@@ -4627,6 +4654,8 @@ void find_libc_lib_path(CodeGen *g) {
} else if (g->zig_target.os == OsLinux) {
g->libc_lib_dir = get_linux_libc_lib_path("crt1.o");
+ } else if (g->zig_target.os == OsFreeBSD) {
+ g->libc_lib_dir = buf_create_from_str("/usr/lib");
} else {
zig_panic("Unable to determine libc lib path.");
}
@@ -4639,6 +4668,8 @@ void find_libc_lib_path(CodeGen *g) {
return;
} else if (g->zig_target.os == OsLinux) {
g->libc_static_lib_dir = get_linux_libc_lib_path("crtbegin.o");
+ } else if (g->zig_target.os == OsFreeBSD) {
+ g->libc_static_lib_dir = buf_create_from_str("/usr/lib");
} else {
zig_panic("Unable to determine libc static lib path.");
}
@@ -5089,7 +5120,10 @@ bool type_has_bits(ZigType *type_entry) {
return !type_entry->zero_bits;
}
-bool type_requires_comptime(ZigType *type_entry) {
+ReqCompTime type_requires_comptime(CodeGen *g, ZigType *type_entry) {
+ Error err;
+ if ((err = type_resolve(g, type_entry, ResolveStatusZeroBitsKnown)))
+ return ReqCompTimeInvalid;
switch (type_entry->id) {
case ZigTypeIdInvalid:
case ZigTypeIdOpaque:
@@ -5102,27 +5136,25 @@ bool type_requires_comptime(ZigType *type_entry) {
case ZigTypeIdNamespace:
case ZigTypeIdBoundFn:
case ZigTypeIdArgTuple:
- return true;
+ return ReqCompTimeYes;
case ZigTypeIdArray:
- return type_requires_comptime(type_entry->data.array.child_type);
+ return type_requires_comptime(g, type_entry->data.array.child_type);
case ZigTypeIdStruct:
- assert(type_is_resolved(type_entry, ResolveStatusZeroBitsKnown));
- return type_entry->data.structure.requires_comptime;
+ return type_entry->data.structure.requires_comptime ? ReqCompTimeYes : ReqCompTimeNo;
case ZigTypeIdUnion:
- assert(type_is_resolved(type_entry, ResolveStatusZeroBitsKnown));
- return type_entry->data.unionation.requires_comptime;
+ return type_entry->data.unionation.requires_comptime ? ReqCompTimeYes : ReqCompTimeNo;
case ZigTypeIdOptional:
- return type_requires_comptime(type_entry->data.maybe.child_type);
+ return type_requires_comptime(g, type_entry->data.maybe.child_type);
case ZigTypeIdErrorUnion:
- return type_requires_comptime(type_entry->data.error_union.payload_type);
+ return type_requires_comptime(g, type_entry->data.error_union.payload_type);
case ZigTypeIdPointer:
if (type_entry->data.pointer.child_type->id == ZigTypeIdOpaque) {
- return false;
+ return ReqCompTimeNo;
} else {
- return type_requires_comptime(type_entry->data.pointer.child_type);
+ return type_requires_comptime(g, type_entry->data.pointer.child_type);
}
case ZigTypeIdFn:
- return type_entry->data.fn.is_generic;
+ return type_entry->data.fn.is_generic ? ReqCompTimeYes : ReqCompTimeNo;
case ZigTypeIdEnum:
case ZigTypeIdErrorSet:
case ZigTypeIdBool:
@@ -5131,7 +5163,7 @@ bool type_requires_comptime(ZigType *type_entry) {
case ZigTypeIdVoid:
case ZigTypeIdUnreachable:
case ZigTypeIdPromise:
- return false;
+ return ReqCompTimeNo;
}
zig_unreachable();
}
@@ -6090,6 +6122,8 @@ uint32_t zig_llvm_fn_key_hash(ZigLLVMFnKey x) {
return (uint32_t)(x.data.floating.bit_count) * (uint32_t)1953839089;
case ZigLLVMFnIdSqrt:
return (uint32_t)(x.data.floating.bit_count) * (uint32_t)2225366385;
+ case ZigLLVMFnIdBswap:
+ return (uint32_t)(x.data.bswap.bit_count) * (uint32_t)3661994335;
case ZigLLVMFnIdOverflowArithmetic:
return ((uint32_t)(x.data.overflow_arithmetic.bit_count) * 87135777) +
((uint32_t)(x.data.overflow_arithmetic.add_sub_mul) * 31640542) +
@@ -6108,6 +6142,8 @@ bool zig_llvm_fn_key_eql(ZigLLVMFnKey a, ZigLLVMFnKey b) {
return a.data.clz.bit_count == b.data.clz.bit_count;
case ZigLLVMFnIdPopCount:
return a.data.pop_count.bit_count == b.data.pop_count.bit_count;
+ case ZigLLVMFnIdBswap:
+ return a.data.bswap.bit_count == b.data.bswap.bit_count;
case ZigLLVMFnIdFloor:
case ZigLLVMFnIdCeil:
case ZigLLVMFnIdSqrt: