aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorgingerBill <bill@gingerbill.org>2022-11-11 15:54:33 +0000
committergingerBill <bill@gingerbill.org>2022-11-11 15:54:33 +0000
commit2b83f27f065d2805e149da23fb1d3c766889491d (patch)
treed9c23dfeda4063c075adc5296fc410d466e8bf43 /src
parent22840ddf9769c47f8ac0f68b5b12f75200229bd9 (diff)
parent3d0e19429818781882deca35df730b3766bade5d (diff)
Merge branch 'master' into map-dev
Diffstat (limited to 'src')
-rw-r--r--src/check_builtin.cpp7
-rw-r--r--src/llvm_backend_proc.cpp18
-rw-r--r--src/types.cpp3
3 files changed, 19 insertions, 9 deletions
diff --git a/src/check_builtin.cpp b/src/check_builtin.cpp
index 890f7a39b..031ef1218 100644
--- a/src/check_builtin.cpp
+++ b/src/check_builtin.cpp
@@ -4182,6 +4182,13 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32
return false;
}
+ Type *elem = type_deref(ptr0.type);
+ if (type_size_of(elem) == 0) {
+ gbString str = type_to_string(ptr0.type);
+ error(ptr0.expr, "Expected a pointer to a non-zero sized element for '%.*s', got %s", LIT(builtin_name), str);
+ gb_string_free(str);
+ return false
+ }
}
break;
diff --git a/src/llvm_backend_proc.cpp b/src/llvm_backend_proc.cpp
index 4b0323855..eaff6edc0 100644
--- a/src/llvm_backend_proc.cpp
+++ b/src/llvm_backend_proc.cpp
@@ -2125,17 +2125,17 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv,
}
case BuiltinProc_ptr_sub:
{
- lbValue ptr0 = lb_build_expr(p, ce->args[0]);
- lbValue ptr1 = lb_build_expr(p, ce->args[1]);
+ Type *elem0 = type_deref(type_of_expr(ce->args[0]));
+ Type *elem1 = type_deref(type_of_expr(ce->args[1]));
+ GB_ASSERT(are_types_identical(elem0, elem1));
+ Type *elem = elem0;
- LLVMTypeRef type_int = lb_type(p->module, t_int);
- LLVMValueRef diff = LLVMBuildPtrDiff2(p->builder, lb_type(p->module, ptr0.type), ptr0.value, ptr1.value, "");
- diff = LLVMBuildIntCast2(p->builder, diff, type_int, /*signed*/true, "");
+ lbValue ptr0 = lb_emit_conv(p, lb_build_expr(p, ce->args[0]), t_uintptr);
+ lbValue ptr1 = lb_emit_conv(p, lb_build_expr(p, ce->args[1]), t_uintptr);
- lbValue res = {};
- res.type = t_int;
- res.value = diff;
- return res;
+ lbValue diff = lb_emit_arith(p, Token_Sub, ptr0, ptr1, t_uintptr);
+ diff = lb_emit_conv(p, diff, t_int);
+ return lb_emit_arith(p, Token_Quo, diff, lb_const_int(p->module, t_int, type_size_of(elem)), t_int);
}
diff --git a/src/types.cpp b/src/types.cpp
index 47007491d..b7bfe1b0f 100644
--- a/src/types.cpp
+++ b/src/types.cpp
@@ -1260,6 +1260,9 @@ bool is_type_typed(Type *t) {
}
bool is_type_untyped(Type *t) {
t = base_type(t);
+ if (t == nullptr) {
+ return false;
+ }
if (t->kind == Type_Basic) {
return (t->Basic.flags & BasicFlag_Untyped) != 0;
}