aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorgingerBill <bill@gingerbill.org>2023-06-07 00:10:39 +0100
committergingerBill <bill@gingerbill.org>2023-06-07 00:10:39 +0100
commit2bc5e0ebd71f1337cf5c3820cb4b623a29e90fbe (patch)
treedd396912c18c8ef663ef041ea905a6647a5a2874 /src
parentca6cef9a7ddb1e3714cc9f5a43053bc7a240b115 (diff)
Fix non-constant compound literals of slices
Diffstat (limited to 'src')
-rw-r--r--src/llvm_backend_const.cpp22
-rw-r--r--src/llvm_backend_expr.cpp5
-rw-r--r--src/llvm_backend_general.cpp26
-rw-r--r--src/llvm_backend_stmt.cpp1
4 files changed, 43 insertions, 11 deletions
diff --git a/src/llvm_backend_const.cpp b/src/llvm_backend_const.cpp
index c8f1fea0f..c9d2f5b26 100644
--- a/src/llvm_backend_const.cpp
+++ b/src/llvm_backend_const.cpp
@@ -131,6 +131,25 @@ gb_internal lbValue lb_const_ptr_cast(lbModule *m, lbValue value, Type *t) {
return res;
}
+
+gb_internal LLVMValueRef llvm_const_string_internal(lbModule *m, Type *t, LLVMValueRef data, LLVMValueRef len) {
+ if (build_context.metrics.ptr_size < build_context.metrics.int_size) {
+ LLVMValueRef values[3] = {
+ data,
+ LLVMConstNull(lb_type(m, t_i32)),
+ len,
+ };
+ return llvm_const_named_struct_internal(lb_type(m, t), values, 3);
+ } else {
+ LLVMValueRef values[2] = {
+ data,
+ len,
+ };
+ return llvm_const_named_struct_internal(lb_type(m, t), values, 2);
+ }
+}
+
+
gb_internal LLVMValueRef llvm_const_named_struct(lbModule *m, Type *t, LLVMValueRef *values, isize value_count_) {
LLVMTypeRef struct_type = lb_type(m, t);
GB_ASSERT(LLVMGetTypeKind(struct_type) == LLVMStructTypeKind);
@@ -659,10 +678,9 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bo
ptr = LLVMConstNull(lb_type(m, t_u8_ptr));
}
LLVMValueRef str_len = LLVMConstInt(lb_type(m, t_int), value.value_string.len, true);
- LLVMValueRef values[2] = {ptr, str_len};
GB_ASSERT(is_type_string(original_type));
- res.value = llvm_const_named_struct(m, original_type, values, 2);
+ res.value = llvm_const_string_internal(m, original_type, ptr, str_len);
}
return res;
diff --git a/src/llvm_backend_expr.cpp b/src/llvm_backend_expr.cpp
index b2adc254d..f95e351ce 100644
--- a/src/llvm_backend_expr.cpp
+++ b/src/llvm_backend_expr.cpp
@@ -4230,11 +4230,12 @@ gb_internal lbAddr lb_build_addr_compound_lit(lbProcedure *p, Ast *expr) {
lbValue count = {};
count.type = t_int;
+ unsigned len_index = lb_convert_struct_index(p->module, type, 1);
if (lb_is_const(slice)) {
- unsigned indices[1] = {1};
+ unsigned indices[1] = {len_index};
count.value = LLVMConstExtractValue(slice.value, indices, gb_count_of(indices));
} else {
- count.value = LLVMBuildExtractValue(p->builder, slice.value, 1, "");
+ count.value = LLVMBuildExtractValue(p->builder, slice.value, len_index, "");
}
lb_fill_slice(p, v, data, count);
}
diff --git a/src/llvm_backend_general.cpp b/src/llvm_backend_general.cpp
index 5cb339eb7..7f25d57b2 100644
--- a/src/llvm_backend_general.cpp
+++ b/src/llvm_backend_general.cpp
@@ -1,4 +1,5 @@
gb_internal void lb_add_debug_local_variable(lbProcedure *p, LLVMValueRef ptr, Type *type, Token const &token);
+gb_internal LLVMValueRef llvm_const_string_internal(lbModule *m, Type *t, LLVMValueRef data, LLVMValueRef len);
gb_global Entity *lb_global_type_info_data_entity = {};
gb_global lbAddr lb_global_type_info_member_types = {};
@@ -1776,11 +1777,23 @@ gb_internal LLVMTypeRef lb_type_internal(lbModule *m, Type *type) {
return type;
}
type = LLVMStructCreateNamed(ctx, name);
- LLVMTypeRef fields[2] = {
- LLVMPointerType(lb_type(m, t_u8), 0),
- lb_type(m, t_int),
- };
- LLVMStructSetBody(type, fields, 2, false);
+
+ if (build_context.metrics.ptr_size < build_context.metrics.int_size) {
+ GB_ASSERT(build_context.metrics.ptr_size == 4);
+ GB_ASSERT(build_context.metrics.int_size == 8);
+ LLVMTypeRef fields[3] = {
+ LLVMPointerType(lb_type(m, t_u8), 0),
+ lb_type(m, t_i32),
+ lb_type(m, t_int),
+ };
+ LLVMStructSetBody(type, fields, 3, false);
+ } else {
+ LLVMTypeRef fields[2] = {
+ LLVMPointerType(lb_type(m, t_u8), 0),
+ lb_type(m, t_int),
+ };
+ LLVMStructSetBody(type, fields, 2, false);
+ }
return type;
}
case Basic_cstring: return LLVMPointerType(LLVMInt8TypeInContext(ctx), 0);
@@ -2533,10 +2546,9 @@ gb_internal lbValue lb_find_or_add_entity_string(lbModule *m, String const &str)
ptr = LLVMConstNull(lb_type(m, t_u8_ptr));
}
LLVMValueRef str_len = LLVMConstInt(lb_type(m, t_int), str.len, true);
- LLVMValueRef values[2] = {ptr, str_len};
lbValue res = {};
- res.value = llvm_const_named_struct(m, t_string, values, 2);
+ res.value = llvm_const_string_internal(m, t_string, ptr, str_len);
res.type = t_string;
return res;
}
diff --git a/src/llvm_backend_stmt.cpp b/src/llvm_backend_stmt.cpp
index 35fd2b7de..275d1f728 100644
--- a/src/llvm_backend_stmt.cpp
+++ b/src/llvm_backend_stmt.cpp
@@ -2471,6 +2471,7 @@ gb_internal void lb_build_stmt(lbProcedure *p, Ast *node) {
}
GB_ASSERT(lval_index == lvals.count);
+
for_array(i, vd->names) {
Ast *name = vd->names[i];
if (!is_blank_ident(name) && !lvals_preused[i]) {