mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
Fix of nested union/struct initialization. Fixes #886.
This commit is contained in:
@@ -1682,16 +1682,15 @@ static LLVMValueRef llvm_recursive_set_value(GenContext *c, DesignatorElement **
|
||||
}
|
||||
|
||||
|
||||
void llvm_emit_initialize_reference_temporary_const(GenContext *c, BEValue *ref, Expr *expr)
|
||||
void llvm_emit_initialize_reference_temporary_const(GenContext *c, BEValue *ref, ConstInitializer *initializer)
|
||||
{
|
||||
bool modified = false;
|
||||
// First create the constant value.
|
||||
|
||||
assert(expr_is_const_initializer(expr));
|
||||
LLVMValueRef value = llvm_emit_const_initializer(c, expr->const_expr.initializer);
|
||||
LLVMValueRef value = llvm_emit_const_initializer(c, initializer);
|
||||
|
||||
// Create a global const.
|
||||
AlignSize alignment = type_alloca_alignment(expr->type);
|
||||
AlignSize alignment = type_alloca_alignment(initializer->type);
|
||||
LLVMTypeRef type = LLVMTypeOf(value);
|
||||
LLVMValueRef global_copy = llvm_add_global_raw(c, ".__const", type, alignment);
|
||||
llvm_set_private_linkage(global_copy);
|
||||
@@ -1705,11 +1704,49 @@ void llvm_emit_initialize_reference_temporary_const(GenContext *c, BEValue *ref,
|
||||
llvm_value_addr(c, ref);
|
||||
|
||||
// Perform the memcpy.
|
||||
llvm_emit_memcpy(c, ref->value, ref->alignment, global_copy, alignment, type_size(expr->type));
|
||||
llvm_emit_memcpy(c, ref->value, ref->alignment, global_copy, alignment, type_size(initializer->type));
|
||||
}
|
||||
|
||||
static inline void llvm_emit_const_initialize_bitstruct_ref(GenContext *c, BEValue *ref, ConstInitializer *initializer)
|
||||
{
|
||||
if (initializer->kind == CONST_INIT_ZERO)
|
||||
{
|
||||
llvm_store_zero(c, ref);
|
||||
return;
|
||||
}
|
||||
assert(initializer->kind == CONST_INIT_STRUCT);
|
||||
llvm_store_raw(c, ref, llvm_emit_const_bitstruct(c, initializer));
|
||||
}
|
||||
|
||||
static void llvm_emit_const_init_ref(GenContext *c, BEValue *ref, ConstInitializer *const_init)
|
||||
{
|
||||
if (const_init->type->type_kind == TYPE_VECTOR)
|
||||
{
|
||||
LLVMValueRef val = llvm_emit_const_initializer(c, const_init);
|
||||
llvm_store_raw(c, ref, val);
|
||||
return;
|
||||
}
|
||||
if (const_init->type->type_kind == TYPE_BITSTRUCT)
|
||||
{
|
||||
llvm_emit_const_initialize_bitstruct_ref(c, ref, const_init);
|
||||
return;
|
||||
}
|
||||
if (const_init->kind == CONST_INIT_ZERO)
|
||||
{
|
||||
// In case of a zero, optimize.
|
||||
llvm_store_zero(c, ref);
|
||||
return;
|
||||
}
|
||||
// In case of small const initializers, or full arrays - use copy.
|
||||
if (const_init->kind == CONST_INIT_ARRAY_FULL || type_size(const_init->type) <= 32)
|
||||
{
|
||||
llvm_emit_initialize_reference_temporary_const(c, ref, const_init);
|
||||
return;
|
||||
}
|
||||
|
||||
// Make sure we have an address.
|
||||
llvm_value_addr(c, ref);
|
||||
|
||||
switch (const_init->kind)
|
||||
{
|
||||
case CONST_INIT_ZERO:
|
||||
@@ -1800,16 +1837,6 @@ static void llvm_emit_const_init_ref(GenContext *c, BEValue *ref, ConstInitializ
|
||||
UNREACHABLE
|
||||
}
|
||||
|
||||
static inline void llvm_emit_const_initialize_struct_union_array(GenContext *c, BEValue *ref, Expr *expr)
|
||||
{
|
||||
assert(expr_is_const_initializer(expr));
|
||||
ConstInitializer *initializer = expr->const_expr.initializer;
|
||||
|
||||
// Make sure we have an address.
|
||||
llvm_value_addr(c, ref);
|
||||
llvm_emit_const_init_ref(c, ref, initializer);
|
||||
|
||||
}
|
||||
static inline void llvm_emit_initialize_reference_vector(GenContext *c, BEValue *ref, Type *real_type, Expr **elements)
|
||||
{
|
||||
llvm_value_addr(c, ref);
|
||||
@@ -2244,16 +2271,6 @@ LLVMValueRef llvm_emit_const_bitstruct(GenContext *c, ConstInitializer *initiali
|
||||
return result;
|
||||
}
|
||||
|
||||
static inline void llvm_emit_const_initialize_bitstruct_ref(GenContext *c, BEValue *ref, ConstInitializer *initializer)
|
||||
{
|
||||
if (initializer->kind == CONST_INIT_ZERO)
|
||||
{
|
||||
llvm_store_zero(c, ref);
|
||||
return;
|
||||
}
|
||||
assert(initializer->kind == CONST_INIT_STRUCT);
|
||||
llvm_store_raw(c, ref, llvm_emit_const_bitstruct(c, initializer));
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize a constant aggregate type.
|
||||
@@ -2261,31 +2278,7 @@ static inline void llvm_emit_const_initialize_bitstruct_ref(GenContext *c, BEVal
|
||||
static inline void llvm_emit_const_initialize_reference(GenContext *c, BEValue *ref, Expr *expr)
|
||||
{
|
||||
assert(expr_is_const_initializer(expr));
|
||||
ConstInitializer *initializer = expr->const_expr.initializer;
|
||||
if (initializer->type->type_kind == TYPE_VECTOR)
|
||||
{
|
||||
LLVMValueRef val = llvm_emit_const_initializer(c, initializer);
|
||||
llvm_store_raw(c, ref, val);
|
||||
return;
|
||||
}
|
||||
if (initializer->type->type_kind == TYPE_BITSTRUCT)
|
||||
{
|
||||
llvm_emit_const_initialize_bitstruct_ref(c, ref, initializer);
|
||||
return;
|
||||
}
|
||||
if (initializer->kind == CONST_INIT_ZERO)
|
||||
{
|
||||
// In case of a zero, optimize.
|
||||
llvm_store_zero(c, ref);
|
||||
return;
|
||||
}
|
||||
// In case of small const initializers, or full arrays - use copy.
|
||||
if (initializer->kind == CONST_INIT_ARRAY_FULL || type_size(expr->type) <= 32)
|
||||
{
|
||||
llvm_emit_initialize_reference_temporary_const(c, ref, expr);
|
||||
return;
|
||||
}
|
||||
llvm_emit_const_initialize_struct_union_array(c, ref, expr);
|
||||
llvm_emit_const_init_ref(c, ref, expr->const_expr.initializer);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -483,7 +483,7 @@ void llvm_emit_dynamic_functions(GenContext *context, Decl **funcs);
|
||||
BEValue llvm_emit_assign_expr(GenContext *c, BEValue *ref, Expr *expr, LLVMValueRef optional);
|
||||
INLINE void llvm_emit_exprid(GenContext *c, BEValue *value, ExprId expr);
|
||||
INLINE void llvm_emit_statement_chain(GenContext *c, AstId current);
|
||||
void llvm_emit_initialize_reference_temporary_const(GenContext *c, BEValue *ref, Expr *expr);
|
||||
void llvm_emit_initialize_reference_temporary_const(GenContext *c, BEValue *ref, ConstInitializer *initializer);
|
||||
void llvm_emit_len_for_expr(GenContext *c, BEValue *be_value, BEValue *expr_to_len);
|
||||
LLVMValueRef llvm_get_ref(GenContext *c, Decl *decl);
|
||||
LLVMValueRef llvm_emit_call_intrinsic(GenContext *c, unsigned intrinsic, LLVMTypeRef *types, unsigned type_count, LLVMValueRef *values, unsigned arg_count);
|
||||
|
||||
@@ -1 +1 @@
|
||||
#define COMPILER_VERSION "0.4.581"
|
||||
#define COMPILER_VERSION "0.4.582"
|
||||
@@ -65,7 +65,7 @@ entry:
|
||||
%6 = getelementptr inbounds %c, ptr %2, i32 0, i32 3
|
||||
store double 0.000000e+00, ptr %6, align 8
|
||||
%7 = getelementptr inbounds %c, ptr %2, i32 0, i32 4
|
||||
store double 3.300000e+00, ptr %7, align 8
|
||||
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %7, ptr align 8 @.__const, i32 8, i1 false)
|
||||
%8 = getelementptr inbounds %ExtraSimple, ptr %a, i32 0, i32 3
|
||||
%9 = getelementptr inbounds %.anon, ptr %8, i32 0, i32 0
|
||||
store i32 0, ptr %9, align 8
|
||||
|
||||
@@ -69,25 +69,25 @@ entry:
|
||||
%m2 = alloca %Matrix2x2_b, align 4
|
||||
%0 = getelementptr inbounds %Matrix3x3, ptr %x, i32 0, i32 0
|
||||
%1 = getelementptr inbounds %.anon.0, ptr %0, i32 0, i32 0
|
||||
store float 1.000000e+00, ptr %1, align 4
|
||||
call void @llvm.memcpy.p0.p0.i32(ptr align 4 %1, ptr align 4 @.__const, i32 4, i1 false)
|
||||
%2 = getelementptr inbounds %.anon.0, ptr %0, i32 0, i32 1
|
||||
store float 2.000000e+00, ptr %2, align 4
|
||||
call void @llvm.memcpy.p0.p0.i32(ptr align 4 %2, ptr align 4 @.__const.16, i32 4, i1 false)
|
||||
%3 = getelementptr inbounds %.anon.0, ptr %0, i32 0, i32 2
|
||||
store float 3.000000e+00, ptr %3, align 4
|
||||
call void @llvm.memcpy.p0.p0.i32(ptr align 4 %3, ptr align 4 @.__const.17, i32 4, i1 false)
|
||||
%4 = getelementptr inbounds %.anon.0, ptr %0, i32 0, i32 3
|
||||
store float 4.000000e+00, ptr %4, align 4
|
||||
call void @llvm.memcpy.p0.p0.i32(ptr align 4 %4, ptr align 4 @.__const.18, i32 4, i1 false)
|
||||
%5 = getelementptr inbounds %.anon.0, ptr %0, i32 0, i32 4
|
||||
store float 5.000000e+00, ptr %5, align 4
|
||||
call void @llvm.memcpy.p0.p0.i32(ptr align 4 %5, ptr align 4 @.__const.19, i32 4, i1 false)
|
||||
%6 = getelementptr inbounds %.anon.0, ptr %0, i32 0, i32 5
|
||||
store float 6.000000e+00, ptr %6, align 4
|
||||
call void @llvm.memcpy.p0.p0.i32(ptr align 4 %6, ptr align 4 @.__const.20, i32 4, i1 false)
|
||||
%7 = getelementptr inbounds %.anon.0, ptr %0, i32 0, i32 6
|
||||
store float 7.000000e+00, ptr %7, align 4
|
||||
call void @llvm.memcpy.p0.p0.i32(ptr align 4 %7, ptr align 4 @.__const.21, i32 4, i1 false)
|
||||
%8 = getelementptr inbounds %.anon.0, ptr %0, i32 0, i32 7
|
||||
store float 8.000000e+00, ptr %8, align 4
|
||||
call void @llvm.memcpy.p0.p0.i32(ptr align 4 %8, ptr align 4 @.__const.22, i32 4, i1 false)
|
||||
%9 = getelementptr inbounds %.anon.0, ptr %0, i32 0, i32 8
|
||||
store float 9.000000e+00, ptr %9, align 4
|
||||
call void @llvm.memcpy.p0.p0.i32(ptr align 4 %m, ptr align 4 @.__const, i32 16, i1 false)
|
||||
call void @llvm.memcpy.p0.p0.i32(ptr align 4 %m2, ptr align 4 @.__const.16, i32 16, i1 false)
|
||||
call void @llvm.memcpy.p0.p0.i32(ptr align 4 %9, ptr align 4 @.__const.23, i32 4, i1 false)
|
||||
call void @llvm.memcpy.p0.p0.i32(ptr align 4 %m, ptr align 4 @.__const.24, i32 16, i1 false)
|
||||
call void @llvm.memcpy.p0.p0.i32(ptr align 4 %m2, ptr align 4 @.__const.25, i32 16, i1 false)
|
||||
%10 = getelementptr inbounds %Matrix3x3, ptr %x, i32 0, i32 0
|
||||
%11 = getelementptr inbounds %.anon.0, ptr %10, i32 0, i32 0
|
||||
%12 = load float, ptr %11, align 4
|
||||
|
||||
Reference in New Issue
Block a user