mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
Macros with default arguments to &, # and type parameters didn't work as expected. #1754.
This commit is contained in:
@@ -41,6 +41,7 @@
|
||||
- Fix bug when including compile time parameters in trailing body more than once.
|
||||
- Fix issue with compiling a constant struct containing a string array in a local context.
|
||||
- Fix error where panic would not properly stop the program when stacktrace couldn't be printed #1751.
|
||||
- Macros with default arguments to `&`, `#` and type parameters didn't work as expected. #1754.
|
||||
|
||||
### Stdlib changes
|
||||
- Increase BitWriter.write_bits limit up to 32 bits.
|
||||
|
||||
@@ -1267,7 +1267,6 @@ static bool sema_analyse_parameter(SemaContext *context, Expr *arg, Decl *param,
|
||||
{
|
||||
VarDeclKind kind = param->var.kind;
|
||||
Type *type = param->type;
|
||||
|
||||
// 16. Analyse a regular argument.
|
||||
switch (kind)
|
||||
{
|
||||
@@ -1403,7 +1402,7 @@ static bool sema_analyse_parameter(SemaContext *context, Expr *arg, Decl *param,
|
||||
case VARDECL_ERASE:
|
||||
UNREACHABLE
|
||||
}
|
||||
if (param && type_len_is_inferred(type))
|
||||
if (type_len_is_inferred(type))
|
||||
{
|
||||
param->type = type_no_optional(arg->type);
|
||||
}
|
||||
@@ -1417,6 +1416,7 @@ INLINE bool sema_set_default_argument(SemaContext *context, CalledDecl *callee,
|
||||
Expr *init_expr = param->var.init_expr;
|
||||
if (!init_expr) return true;
|
||||
Expr *arg = copy_expr_single(init_expr);
|
||||
bool parameter_checked = false;
|
||||
if (arg->resolve_status != RESOLVE_DONE)
|
||||
{
|
||||
SemaContext default_context;
|
||||
@@ -1436,20 +1436,20 @@ INLINE bool sema_set_default_argument(SemaContext *context, CalledDecl *callee,
|
||||
{
|
||||
RETURN_NOTE_FUNC_DEFINITION;
|
||||
}
|
||||
if (!success) return false;
|
||||
parameter_checked = true;
|
||||
}
|
||||
if (sema_cast_const(arg))
|
||||
switch (param->var.kind)
|
||||
{
|
||||
switch (param->var.kind)
|
||||
{
|
||||
case VARDECL_PARAM_CT:
|
||||
case VARDECL_PARAM_CT_TYPE:
|
||||
case VARDECL_PARAM_EXPR:
|
||||
*expr_ref = arg;
|
||||
return sema_analyse_parameter(context, arg, param, callee->definition, optional, no_match_ref,
|
||||
callee->macro, false);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
case VARDECL_PARAM_CT:
|
||||
case VARDECL_PARAM_CT_TYPE:
|
||||
case VARDECL_PARAM_EXPR:
|
||||
*expr_ref = arg;
|
||||
if (parameter_checked) return true;
|
||||
return sema_analyse_parameter(context, arg, param, callee->definition, optional, no_match_ref,
|
||||
callee->macro, false);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
Expr *function_scope_arg = expr_new(EXPR_DEFAULT_ARG, arg->span);
|
||||
function_scope_arg->resolve_status = RESOLVE_DONE;
|
||||
@@ -1457,6 +1457,7 @@ INLINE bool sema_set_default_argument(SemaContext *context, CalledDecl *callee,
|
||||
function_scope_arg->default_arg_expr.inner = arg;
|
||||
function_scope_arg->default_arg_expr.loc = callee->call_location;
|
||||
*expr_ref = function_scope_arg;
|
||||
if (parameter_checked) return true;
|
||||
return sema_analyse_parameter(context, function_scope_arg, param, callee->definition, optional, no_match_ref,
|
||||
callee->macro, false);
|
||||
}
|
||||
@@ -9784,6 +9785,10 @@ bool sema_analyse_expr(SemaContext *context, Expr *expr)
|
||||
|
||||
bool sema_cast_const(Expr *expr)
|
||||
{
|
||||
if (expr->resolve_status != RESOLVE_DONE)
|
||||
{
|
||||
puts("Tesst");
|
||||
}
|
||||
ASSERT_SPAN(expr, expr->resolve_status == RESOLVE_DONE);
|
||||
switch (expr->expr_kind)
|
||||
{
|
||||
|
||||
348
test/test_suite/statements/default_macro_argc.c3t
Normal file
348
test/test_suite/statements/default_macro_argc.c3t
Normal file
@@ -0,0 +1,348 @@
|
||||
module test;
|
||||
import std, test2;
|
||||
|
||||
int[2] x;
|
||||
|
||||
macro @test2(&a = x[1])
|
||||
{
|
||||
*a = 123;
|
||||
}
|
||||
macro test($Type = int) { io::printn($Type.nameof); }
|
||||
|
||||
fn void testme() { io::printn("Testme"); }
|
||||
macro @test3(#foo = testme()) => #foo;
|
||||
|
||||
fn void main()
|
||||
{
|
||||
test();
|
||||
@test2();
|
||||
@test3();
|
||||
io::printn(x);
|
||||
test2::test();
|
||||
test2::@test2();
|
||||
test2::@test3();
|
||||
io::printn(test2::x);
|
||||
|
||||
}
|
||||
|
||||
module test2;
|
||||
import std;
|
||||
|
||||
int[2] x;
|
||||
|
||||
macro @test2(&a = x[1])
|
||||
{
|
||||
*a = 12;
|
||||
}
|
||||
macro test($Type = double) { io::printn($Type.nameof); }
|
||||
|
||||
fn void testme() { io::printn("Testme2"); }
|
||||
macro @test3(#foo = testme()) => #foo;
|
||||
|
||||
/* #expect: test.ll
|
||||
|
||||
|
||||
define void @test.main() #0 {
|
||||
entry:
|
||||
%len = alloca i64, align 8
|
||||
%error_var = alloca i64, align 8
|
||||
%retparam = alloca i64, align 8
|
||||
%taddr = alloca %"char[]", align 8
|
||||
%error_var2 = alloca i64, align 8
|
||||
%error_var8 = alloca i64, align 8
|
||||
%x = alloca [2 x i32], align 4
|
||||
%x14 = alloca [2 x i32], align 4
|
||||
%len15 = alloca i64, align 8
|
||||
%error_var16 = alloca i64, align 8
|
||||
%x17 = alloca [2 x i32], align 4
|
||||
%varargslots = alloca [1 x %any], align 8
|
||||
%retparam19 = alloca i64, align 8
|
||||
%taddr20 = alloca %any, align 8
|
||||
%taddr21 = alloca %"char[]", align 8
|
||||
%taddr22 = alloca %"any[]", align 8
|
||||
%error_var28 = alloca i64, align 8
|
||||
%error_var34 = alloca i64, align 8
|
||||
%len42 = alloca i64, align 8
|
||||
%error_var43 = alloca i64, align 8
|
||||
%retparam45 = alloca i64, align 8
|
||||
%taddr46 = alloca %"char[]", align 8
|
||||
%error_var52 = alloca i64, align 8
|
||||
%error_var58 = alloca i64, align 8
|
||||
%x66 = alloca [2 x i32], align 4
|
||||
%x67 = alloca [2 x i32], align 4
|
||||
%len68 = alloca i64, align 8
|
||||
%error_var69 = alloca i64, align 8
|
||||
%x70 = alloca [2 x i32], align 4
|
||||
%varargslots72 = alloca [1 x %any], align 8
|
||||
%retparam74 = alloca i64, align 8
|
||||
%taddr75 = alloca %any, align 8
|
||||
%taddr76 = alloca %"char[]", align 8
|
||||
%taddr77 = alloca %"any[]", align 8
|
||||
%error_var83 = alloca i64, align 8
|
||||
%error_var89 = alloca i64, align 8
|
||||
%0 = call ptr @std.io.stdout()
|
||||
store %"char[]" { ptr @.str.1, i64 3 }, ptr %taddr, align 8
|
||||
%1 = load [2 x i64], ptr %taddr, align 8
|
||||
%2 = call i64 @std.io.File.write(ptr %retparam, ptr %0
|
||||
%not_err = icmp eq i64 %2, 0
|
||||
%3 = call i1 @llvm.expect.i1(i1 %not_err, i1 true)
|
||||
br i1 %3, label %after_check, label %assign_optional
|
||||
|
||||
assign_optional: ; preds = %entry
|
||||
store i64 %2, ptr %error_var, align 8
|
||||
br label %guard_block
|
||||
|
||||
after_check: ; preds = %entry
|
||||
br label %noerr_block
|
||||
|
||||
guard_block: ; preds = %assign_optional
|
||||
br label %voiderr
|
||||
|
||||
noerr_block: ; preds = %after_check
|
||||
%4 = load i64, ptr %retparam, align 8
|
||||
store i64 %4, ptr %len, align 8
|
||||
%5 = call i64 @std.io.File.write_byte(ptr %0, i8 10)
|
||||
%not_err3 = icmp eq i64 %5, 0
|
||||
%6 = call i1 @llvm.expect.i1(i1 %not_err3, i1 true)
|
||||
br i1 %6, label %after_check5, label %assign_optional4
|
||||
|
||||
assign_optional4: ; preds = %noerr_block
|
||||
store i64 %5, ptr %error_var2, align 8
|
||||
br label %guard_block6
|
||||
|
||||
after_check5: ; preds = %noerr_block
|
||||
br label %noerr_block7
|
||||
|
||||
guard_block6: ; preds = %assign_optional4
|
||||
br label %voiderr
|
||||
|
||||
noerr_block7: ; preds = %after_check5
|
||||
%7 = call i64 @std.io.File.flush(ptr %0)
|
||||
%not_err9 = icmp eq i64 %7, 0
|
||||
%8 = call i1 @llvm.expect.i1(i1 %not_err9, i1 true)
|
||||
br i1 %8, label %after_check11, label %assign_optional10
|
||||
|
||||
assign_optional10: ; preds = %noerr_block7
|
||||
store i64 %7, ptr %error_var8, align 8
|
||||
br label %guard_block12
|
||||
|
||||
after_check11: ; preds = %noerr_block7
|
||||
br label %noerr_block13
|
||||
|
||||
guard_block12: ; preds = %assign_optional10
|
||||
br label %voiderr
|
||||
|
||||
noerr_block13: ; preds = %after_check11
|
||||
%9 = load i64, ptr %len, align 8
|
||||
%add = add i64 %9, 1
|
||||
br label %voiderr
|
||||
|
||||
voiderr: ; preds = %noerr_block13, %guard_block12, %guard_block6, %guard_block
|
||||
store i32 123, ptr getelementptr inbounds (i8, ptr @test.x, i64 4), align 4
|
||||
call void @test.testme()
|
||||
call void @llvm.memcpy.p0.p0.i32(ptr align 4 %x, ptr align 4 @test.x, i32 8, i1 false)
|
||||
%10 = call ptr @std.io.stdout()
|
||||
call void @llvm.memcpy.p0.p0.i32(ptr align 4 %x14, ptr align 4 %x, i32 8, i1 false)
|
||||
call void @llvm.memcpy.p0.p0.i32(ptr align 4 %x17, ptr align 4 %x14, i32 8, i1 false)
|
||||
%11 = insertvalue %any undef, ptr %10, 0
|
||||
%12 = insertvalue %any %11, i64 ptrtoint (ptr @"$ct.std.io.File" to i64), 1
|
||||
%13 = insertvalue %any undef, ptr %x17, 0
|
||||
%14 = insertvalue %any %13, i64 ptrtoint (ptr @"$ct.a2$int" to i64), 1
|
||||
store %any %14, ptr %varargslots, align 8
|
||||
%15 = insertvalue %"any[]" undef, ptr %varargslots, 0
|
||||
%"$$temp" = insertvalue %"any[]" %15, i64 1, 1
|
||||
store %any %12, ptr %taddr20, align 8
|
||||
%16 = load [2 x i64], ptr %taddr20, align 8
|
||||
store %"char[]" { ptr @.str.2, i64 2 }, ptr %taddr21, align 8
|
||||
%17 = load [2 x i64], ptr %taddr21, align 8
|
||||
store %"any[]" %"$$temp", ptr %taddr22, align 8
|
||||
%18 = load [2 x i64], ptr %taddr22, align 8
|
||||
%19 = call i64 @std.io.fprintf(ptr %retparam19
|
||||
%not_err23 = icmp eq i64 %19, 0
|
||||
%20 = call i1 @llvm.expect.i1(i1 %not_err23, i1 true)
|
||||
br i1 %20, label %after_check25, label %assign_optional24
|
||||
|
||||
assign_optional24: ; preds = %voiderr
|
||||
store i64 %19, ptr %error_var16, align 8
|
||||
br label %guard_block26
|
||||
|
||||
after_check25: ; preds = %voiderr
|
||||
br label %noerr_block27
|
||||
|
||||
guard_block26: ; preds = %assign_optional24
|
||||
br label %voiderr41
|
||||
|
||||
noerr_block27: ; preds = %after_check25
|
||||
%21 = load i64, ptr %retparam19, align 8
|
||||
store i64 %21, ptr %len15, align 8
|
||||
%22 = call i64 @std.io.File.write_byte(ptr %10, i8 10)
|
||||
%not_err29 = icmp eq i64 %22, 0
|
||||
%23 = call i1 @llvm.expect.i1(i1 %not_err29, i1 true)
|
||||
br i1 %23, label %after_check31, label %assign_optional30
|
||||
|
||||
assign_optional30: ; preds = %noerr_block27
|
||||
store i64 %22, ptr %error_var28, align 8
|
||||
br label %guard_block32
|
||||
|
||||
after_check31: ; preds = %noerr_block27
|
||||
br label %noerr_block33
|
||||
|
||||
guard_block32: ; preds = %assign_optional30
|
||||
br label %voiderr41
|
||||
|
||||
noerr_block33: ; preds = %after_check31
|
||||
%24 = call i64 @std.io.File.flush(ptr %10)
|
||||
%not_err35 = icmp eq i64 %24, 0
|
||||
%25 = call i1 @llvm.expect.i1(i1 %not_err35, i1 true)
|
||||
br i1 %25, label %after_check37, label %assign_optional36
|
||||
|
||||
assign_optional36: ; preds = %noerr_block33
|
||||
store i64 %24, ptr %error_var34, align 8
|
||||
br label %guard_block38
|
||||
|
||||
after_check37: ; preds = %noerr_block33
|
||||
br label %noerr_block39
|
||||
|
||||
guard_block38: ; preds = %assign_optional36
|
||||
br label %voiderr41
|
||||
|
||||
noerr_block39: ; preds = %after_check37
|
||||
%26 = load i64, ptr %len15, align 8
|
||||
%add40 = add i64 %26, 1
|
||||
br label %voiderr41
|
||||
|
||||
voiderr41: ; preds = %noerr_block39, %guard_block38, %guard_block32, %guard_block26
|
||||
%27 = call ptr @std.io.stdout()
|
||||
store %"char[]" { ptr @.str.3, i64 6 }, ptr %taddr46, align 8
|
||||
%28 = load [2 x i64], ptr %taddr46, align 8
|
||||
%29 = call i64 @std.io.File.write(ptr %retparam45
|
||||
%not_err47 = icmp eq i64 %29, 0
|
||||
%30 = call i1 @llvm.expect.i1(i1 %not_err47, i1 true)
|
||||
br i1 %30, label %after_check49, label %assign_optional48
|
||||
|
||||
assign_optional48: ; preds = %voiderr41
|
||||
store i64 %29, ptr %error_var43, align 8
|
||||
br label %guard_block50
|
||||
|
||||
after_check49: ; preds = %voiderr41
|
||||
br label %noerr_block51
|
||||
|
||||
guard_block50: ; preds = %assign_optional48
|
||||
br label %voiderr65
|
||||
|
||||
noerr_block51: ; preds = %after_check49
|
||||
%31 = load i64, ptr %retparam45, align 8
|
||||
store i64 %31, ptr %len42, align 8
|
||||
%32 = call i64 @std.io.File.write_byte(ptr %27, i8 10)
|
||||
%not_err53 = icmp eq i64 %32, 0
|
||||
%33 = call i1 @llvm.expect.i1(i1 %not_err53, i1 true)
|
||||
br i1 %33, label %after_check55, label %assign_optional54
|
||||
|
||||
assign_optional54: ; preds = %noerr_block51
|
||||
store i64 %32, ptr %error_var52, align 8
|
||||
br label %guard_block56
|
||||
|
||||
after_check55: ; preds = %noerr_block51
|
||||
br label %noerr_block57
|
||||
|
||||
guard_block56: ; preds = %assign_optional54
|
||||
br label %voiderr65
|
||||
|
||||
noerr_block57: ; preds = %after_check55
|
||||
%34 = call i64 @std.io.File.flush(ptr %27)
|
||||
%not_err59 = icmp eq i64 %34, 0
|
||||
%35 = call i1 @llvm.expect.i1(i1 %not_err59, i1 true)
|
||||
br i1 %35, label %after_check61, label %assign_optional60
|
||||
|
||||
assign_optional60: ; preds = %noerr_block57
|
||||
store i64 %34, ptr %error_var58, align 8
|
||||
br label %guard_block62
|
||||
|
||||
after_check61: ; preds = %noerr_block57
|
||||
br label %noerr_block63
|
||||
|
||||
guard_block62: ; preds = %assign_optional60
|
||||
br label %voiderr65
|
||||
|
||||
noerr_block63: ; preds = %after_check61
|
||||
%36 = load i64, ptr %len42, align 8
|
||||
%add64 = add i64 %36, 1
|
||||
br label %voiderr65
|
||||
|
||||
voiderr65: ; preds = %noerr_block63, %guard_block62, %guard_block56, %guard_block50
|
||||
store i32 12, ptr getelementptr inbounds
|
||||
call void @test2.testme()
|
||||
call void @llvm.memcpy.p0.p0.i32(ptr align 4 %x66, ptr align 4 @test2.x, i32 8, i1 false)
|
||||
%37 = call ptr @std.io.stdout()
|
||||
call void @llvm.memcpy.p0.p0.i32(ptr align 4 %x67, ptr align 4 %x66, i32 8, i1 false)
|
||||
call void @llvm.memcpy.p0.p0.i32(ptr align 4 %x70, ptr align 4 %x67, i32 8, i1 false)
|
||||
%38 = insertvalue %any undef, ptr %37, 0
|
||||
%39 = insertvalue %any %38, i64 ptrtoint (ptr @"$ct.std.io.File" to i64), 1
|
||||
%40 = insertvalue %any undef, ptr %x70, 0
|
||||
%41 = insertvalue %any %40, i64 ptrtoint (ptr @"$ct.a2$int" to i64), 1
|
||||
store %any %41, ptr %varargslots72, align 8
|
||||
%42 = insertvalue %"any[]" undef, ptr %varargslots72, 0
|
||||
%"$$temp73" = insertvalue %"any[]" %42, i64 1, 1
|
||||
store %any %39, ptr %taddr75, align 8
|
||||
%43 = load [2 x i64], ptr %taddr75, align 8
|
||||
store %"char[]" { ptr @.str.4, i64 2 }, ptr %taddr76, align 8
|
||||
%44 = load [2 x i64], ptr %taddr76, align 8
|
||||
store %"any[]" %"$$temp73", ptr %taddr77, align 8
|
||||
%45 = load [2 x i64], ptr %taddr77, align 8
|
||||
%46 = call i64 @std.io.fprintf(ptr %retparam74
|
||||
%not_err78 = icmp eq i64 %46, 0
|
||||
%47 = call i1 @llvm.expect.i1(i1 %not_err78, i1 true)
|
||||
br i1 %47, label %after_check80, label %assign_optional79
|
||||
|
||||
assign_optional79: ; preds = %voiderr65
|
||||
store i64 %46, ptr %error_var69, align 8
|
||||
br label %guard_block81
|
||||
|
||||
after_check80: ; preds = %voiderr65
|
||||
br label %noerr_block82
|
||||
|
||||
guard_block81: ; preds = %assign_optional79
|
||||
br label %voiderr96
|
||||
|
||||
noerr_block82: ; preds = %after_check80
|
||||
%48 = load i64, ptr %retparam74, align 8
|
||||
store i64 %48, ptr %len68, align 8
|
||||
%49 = call i64 @std.io.File.write_byte(ptr %37, i8 10)
|
||||
%not_err84 = icmp eq i64 %49, 0
|
||||
%50 = call i1 @llvm.expect.i1(i1 %not_err84, i1 true)
|
||||
br i1 %50, label %after_check86, label %assign_optional85
|
||||
|
||||
assign_optional85: ; preds = %noerr_block82
|
||||
store i64 %49, ptr %error_var83, align 8
|
||||
br label %guard_block87
|
||||
|
||||
after_check86: ; preds = %noerr_block82
|
||||
br label %noerr_block88
|
||||
|
||||
guard_block87: ; preds = %assign_optional85
|
||||
br label %voiderr96
|
||||
|
||||
noerr_block88: ; preds = %after_check86
|
||||
%51 = call i64 @std.io.File.flush(ptr %37)
|
||||
%not_err90 = icmp eq i64 %51, 0
|
||||
%52 = call i1 @llvm.expect.i1(i1 %not_err90, i1 true)
|
||||
br i1 %52, label %after_check92, label %assign_optional91
|
||||
|
||||
assign_optional91: ; preds = %noerr_block88
|
||||
store i64 %51, ptr %error_var89, align 8
|
||||
br label %guard_block93
|
||||
|
||||
after_check92: ; preds = %noerr_block88
|
||||
br label %noerr_block94
|
||||
|
||||
guard_block93: ; preds = %assign_optional91
|
||||
br label %voiderr96
|
||||
|
||||
noerr_block94: ; preds = %after_check92
|
||||
%53 = load i64, ptr %len68, align 8
|
||||
%add95 = add i64 %53, 1
|
||||
br label %voiderr96
|
||||
|
||||
voiderr96: ; preds = %noerr_block94, %guard_block93, %guard_block87, %guard_block81
|
||||
ret void
|
||||
}
|
||||
Reference in New Issue
Block a user