mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
LLVM codegen for constants in enums could fail.
This commit is contained in:
@@ -45,6 +45,7 @@
|
|||||||
- Issue where a `if (catch e = ...)` in a defer would be incorrectly copied. Causing codegen error.
|
- Issue where a `if (catch e = ...)` in a defer would be incorrectly copied. Causing codegen error.
|
||||||
- Variable in if-try / if-catch cannot be a reused variable name.
|
- Variable in if-try / if-catch cannot be a reused variable name.
|
||||||
- Vararg interfaces were broken.
|
- Vararg interfaces were broken.
|
||||||
|
- LLVM codegen for constants in enums could fail.
|
||||||
|
|
||||||
### Stdlib changes
|
### Stdlib changes
|
||||||
|
|
||||||
|
|||||||
@@ -402,7 +402,7 @@ LLVMValueRef llvm_emit_const_initializer(GenContext *c, ConstInitializer *const_
|
|||||||
case CONST_INIT_VALUE:
|
case CONST_INIT_VALUE:
|
||||||
{
|
{
|
||||||
BEValue value;
|
BEValue value;
|
||||||
llvm_emit_expr(c, &value, const_init->init_value);
|
llvm_emit_expr_global_value(c, &value, const_init->init_value);
|
||||||
return llvm_load_value_store(c, &value);
|
return llvm_load_value_store(c, &value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -497,7 +497,7 @@ void llvm_emit_global_variable_init(GenContext *c, Decl *decl)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
BEValue value;
|
BEValue value;
|
||||||
llvm_emit_expr(c, &value, init_expr);
|
llvm_emit_expr_global_value(c, &value, init_expr);
|
||||||
init_value = llvm_load_value_store(c, &value);
|
init_value = llvm_load_value_store(c, &value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -558,7 +558,7 @@ void llvm_emit_global_variable_init(GenContext *c, Decl *decl)
|
|||||||
Expr *inner = init_expr->inner_expr;
|
Expr *inner = init_expr->inner_expr;
|
||||||
assert(expr_is_const(inner) && inner->const_expr.const_kind == CONST_ERR);
|
assert(expr_is_const(inner) && inner->const_expr.const_kind == CONST_ERR);
|
||||||
BEValue value;
|
BEValue value;
|
||||||
llvm_emit_expr(c, &value, inner);
|
llvm_emit_expr_global_value(c, &value, inner);
|
||||||
optional_value = llvm_load_value_store(c, &value);
|
optional_value = llvm_load_value_store(c, &value);
|
||||||
}
|
}
|
||||||
if (!decl->is_extern)
|
if (!decl->is_extern)
|
||||||
|
|||||||
@@ -7043,6 +7043,12 @@ static void llvm_emit_default_arg(GenContext *c, BEValue *value, Expr *expr)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void llvm_emit_expr_global_value(GenContext *c, BEValue *value, Expr *expr)
|
||||||
|
{
|
||||||
|
sema_cast_const(expr);
|
||||||
|
llvm_emit_expr(c, value, expr);
|
||||||
|
assert(!llvm_value_is_addr(value));
|
||||||
|
}
|
||||||
void llvm_emit_expr(GenContext *c, BEValue *value, Expr *expr)
|
void llvm_emit_expr(GenContext *c, BEValue *value, Expr *expr)
|
||||||
{
|
{
|
||||||
EMIT_LOC(c, expr);
|
EMIT_LOC(c, expr);
|
||||||
|
|||||||
@@ -502,6 +502,7 @@ void llvm_emit_parameter(GenContext *c, LLVMValueRef *args, unsigned *arg_count_
|
|||||||
LLVMValueRef llvm_get_selector(GenContext *c, const char *name);
|
LLVMValueRef llvm_get_selector(GenContext *c, const char *name);
|
||||||
|
|
||||||
// -- C3 Lowering --
|
// -- C3 Lowering --
|
||||||
|
void llvm_emit_expr_global_value(GenContext *c, BEValue *value, Expr *expr);
|
||||||
void llvm_emit_expr(GenContext *c, BEValue *value, Expr *expr);
|
void llvm_emit_expr(GenContext *c, BEValue *value, Expr *expr);
|
||||||
LLVMValueRef llvm_emit_expr_to_rvalue(GenContext *c, Expr *expr);
|
LLVMValueRef llvm_emit_expr_to_rvalue(GenContext *c, Expr *expr);
|
||||||
LLVMValueRef llvm_emit_exprid_to_rvalue(GenContext *c, ExprId expr_id);
|
LLVMValueRef llvm_emit_exprid_to_rvalue(GenContext *c, ExprId expr_id);
|
||||||
|
|||||||
@@ -538,10 +538,8 @@ static LLVMValueRef llvm_get_introspection_for_enum(GenContext *c, Type *type)
|
|||||||
for (unsigned i = 0; i < elements; i++)
|
for (unsigned i = 0; i < elements; i++)
|
||||||
{
|
{
|
||||||
BEValue value;
|
BEValue value;
|
||||||
llvm_emit_expr(c, &value, enum_vals[i]->enum_constant.args[ai]);
|
llvm_emit_expr_global_value(c, &value, enum_vals[i]->enum_constant.args[ai]);
|
||||||
assert(!llvm_value_is_addr(&value));
|
LLVMValueRef llvm_value = llvm_load_value_store(c, &value);
|
||||||
LLVMValueRef llvm_value = llvm_value_is_bool(&value) ? LLVMBuildZExt(c->builder, value.value, c->byte_type, "")
|
|
||||||
: value.value;
|
|
||||||
values[i] = llvm_value;
|
values[i] = llvm_value;
|
||||||
if (!val_type)
|
if (!val_type)
|
||||||
{
|
{
|
||||||
|
|||||||
55
test/test_suite/enumerations/enum_with_const.c3t
Normal file
55
test/test_suite/enumerations/enum_with_const.c3t
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
// #target: macos-x64
|
||||||
|
module test;
|
||||||
|
|
||||||
|
const FG_YELLOW = "\e[0;38;2;255;240;128m";
|
||||||
|
const FG_GREEN = "\e[0;38;2;192;255;192m";
|
||||||
|
const FG_RED = "\e[0;38;2;255;40;40m";
|
||||||
|
|
||||||
|
enum SeverityTag : int (String fg, String label) {
|
||||||
|
INFO = { FG_GREEN, "info" },
|
||||||
|
WARN = { FG_YELLOW, "warn" },
|
||||||
|
FATAL = { FG_RED, "fatal" },
|
||||||
|
FATAL2 = { FG_RED, "fatal2" },
|
||||||
|
}
|
||||||
|
|
||||||
|
fn void main()
|
||||||
|
{
|
||||||
|
SeverityTag tag = WARN;
|
||||||
|
String a = tag.fg;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* #expect: test.ll
|
||||||
|
|
||||||
|
@.enum.INFO = internal constant [5 x i8] c"INFO\00", align 1
|
||||||
|
@.enum.WARN = internal constant [5 x i8] c"WARN\00", align 1
|
||||||
|
@.enum.FATAL = internal constant [6 x i8] c"FATAL\00", align 1
|
||||||
|
@.enum.FATAL2 = internal constant [7 x i8] c"FATAL2\00", align 1
|
||||||
|
@"$ct.test.SeverityTag" = linkonce global { i8, i64, ptr, i64, i64, i64, [4 x %"char[]"] } { i8 8, i64 0, ptr null, i64 4, i64 ptrtoint (ptr @"$ct.int" to i64), i64 4, [4 x %"char[]"] [%"char[]" { ptr @.enum.INFO, i64 4 }, %"char[]" { ptr @.enum.WARN, i64 4 }, %"char[]" { ptr @.enum.FATAL, i64 5 }, %"char[]" { ptr @.enum.FATAL2, i64 6 }] }, align 8
|
||||||
|
@.str = private unnamed_addr constant [22 x i8] c"\1B[0;38;2;192;255;192m\00", align 1
|
||||||
|
@.str.1 = private unnamed_addr constant [22 x i8] c"\1B[0;38;2;255;240;128m\00", align 1
|
||||||
|
@.str.2 = private unnamed_addr constant [20 x i8] c"\1B[0;38;2;255;40;40m\00", align 1
|
||||||
|
@.str.3 = private unnamed_addr constant [20 x i8] c"\1B[0;38;2;255;40;40m\00", align 1
|
||||||
|
@"test.SeverityTag$fg" = linkonce constant [4 x %"char[]"] [%"char[]" { ptr @.str, i64 21 }, %"char[]" { ptr @.str.1, i64 21 }, %"char[]" { ptr @.str.2, i64 19 }, %"char[]" { ptr @.str.3, i64 19 }], align 8
|
||||||
|
@.str.4 = private unnamed_addr constant [5 x i8] c"info\00", align 1
|
||||||
|
@.str.5 = private unnamed_addr constant [5 x i8] c"warn\00", align 1
|
||||||
|
@.str.6 = private unnamed_addr constant [6 x i8] c"fatal\00", align 1
|
||||||
|
@.str.7 = private unnamed_addr constant [7 x i8] c"fatal2\00", align 1
|
||||||
|
@"test.SeverityTag$label" = linkonce constant [4 x %"char[]"] [%"char[]" { ptr @.str.4, i64 4 }, %"char[]" { ptr @.str.5, i64 4 }, %"char[]" { ptr @.str.6, i64 5 }, %"char[]" { ptr @.str.7, i64 6 }], align 8
|
||||||
|
@.str.10 = private unnamed_addr constant [22 x i8] c"\1B[0;38;2;255;240;128m\00", align 1
|
||||||
|
@test.FG_YELLOW = local_unnamed_addr constant %"char[]" { ptr @.str.10, i64 21 }, align 8
|
||||||
|
@.str.11 = private unnamed_addr constant [22 x i8] c"\1B[0;38;2;192;255;192m\00", align 1
|
||||||
|
@test.FG_GREEN = local_unnamed_addr constant %"char[]" { ptr @.str.11, i64 21 }, align 8
|
||||||
|
@.str.12 = private unnamed_addr constant [20 x i8] c"\1B[0;38;2;255;40;40m\00", align 1
|
||||||
|
@test.FG_RED = local_unnamed_addr constant %"char[]" { ptr @.str.12, i64 19 }, align 8
|
||||||
|
|
||||||
|
define void @test.main() #0 {
|
||||||
|
entry:
|
||||||
|
%tag = alloca i32, align 4
|
||||||
|
%a = alloca %"char[]", align 8
|
||||||
|
store i32 1, ptr %tag, align 4
|
||||||
|
%0 = load i32, ptr %tag, align 4
|
||||||
|
%ptroffset = getelementptr inbounds [16 x i8], ptr @"test.SeverityTag$fg", i32 %0
|
||||||
|
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %a, ptr align 8 %ptroffset, i32 16, i1 false)
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
Reference in New Issue
Block a user