mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
Assert a try will unwrap. #271
This commit is contained in:
committed by
Christoffer Lerno
parent
f180a0d44a
commit
b4be829c71
@@ -164,6 +164,14 @@ static inline Expr *parse_try_unwrap_chain(Context *context)
|
||||
return try_unwrap_chain;
|
||||
}
|
||||
|
||||
Expr *parse_assert_expr(Context *context)
|
||||
{
|
||||
if (next_is_try_unwrap(context))
|
||||
{
|
||||
return parse_try_unwrap_chain(context);
|
||||
}
|
||||
return parse_expr(context);
|
||||
}
|
||||
/**
|
||||
* cond_list ::= ((expr | decl-expr) COMMA)* (expr | decl-expr | try_unwrap_chain | catch_unwrap )
|
||||
*
|
||||
|
||||
@@ -832,22 +832,6 @@ static Ast *parse_volatile_stmt(Context *context)
|
||||
return ast;
|
||||
}
|
||||
|
||||
static inline bool is_valid_try_statement(TokenType type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case TOKEN_SWITCH:
|
||||
case TOKEN_IF:
|
||||
case TOKEN_FOR:
|
||||
case TOKEN_WHILE:
|
||||
case TOKEN_DO:
|
||||
case TOKEN_RETURN:
|
||||
case TOKEN_LBRACE:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -930,10 +914,10 @@ static inline Ast *parse_assert_stmt(Context *context)
|
||||
Ast *ast = AST_NEW_TOKEN(AST_ASSERT_STMT, context->tok);
|
||||
advance_and_verify(context, TOKEN_ASSERT);
|
||||
TRY_CONSUME_OR(TOKEN_LPAREN, "'assert' needs a '(' here, did you forget it?", poisoned_ast);
|
||||
ast->ct_assert_stmt.expr = TRY_EXPR_OR(parse_expr(context), poisoned_ast);
|
||||
ast->assert_stmt.expr = TRY_EXPR_OR(parse_assert_expr(context), poisoned_ast);
|
||||
if (try_consume(context, TOKEN_COMMA))
|
||||
{
|
||||
ast->ct_assert_stmt.message = TRY_EXPR_OR(parse_expr(context), poisoned_ast);
|
||||
ast->assert_stmt.message = TRY_EXPR_OR(parse_expr(context), poisoned_ast);
|
||||
}
|
||||
TRY_CONSUME_OR(TOKEN_RPAREN, "The ending ')' was expected here.", poisoned_ast);
|
||||
TRY_CONSUME_EOS();
|
||||
|
||||
@@ -46,6 +46,7 @@ void parse_imports(Context *context);
|
||||
Decl *parse_decl(Context *context);
|
||||
void recover_top_level(Context *context);
|
||||
Expr *parse_cond(Context *context);
|
||||
Expr *parse_assert_expr(Context *context);
|
||||
Ast* parse_compound_stmt(Context *context);
|
||||
Ast *parse_jump_stmt_no_eos(Context *context);
|
||||
bool parse_attributes(Context *context, Attr ***attributes_ref);
|
||||
|
||||
@@ -2204,8 +2204,8 @@ bool sema_analyse_ct_assert_stmt(Context *context, Ast *statement)
|
||||
|
||||
bool sema_analyse_assert_stmt(Context *context, Ast *statement)
|
||||
{
|
||||
Expr *expr = statement->ct_assert_stmt.expr;
|
||||
Expr *message = statement->ct_assert_stmt.message;
|
||||
Expr *expr = statement->assert_stmt.expr;
|
||||
Expr *message = statement->assert_stmt.message;
|
||||
if (message)
|
||||
{
|
||||
if (!sema_analyse_expr(context, type_compstr, message)) return false;
|
||||
@@ -2214,7 +2214,14 @@ bool sema_analyse_assert_stmt(Context *context, Ast *statement)
|
||||
SEMA_ERROR(message, "Expected a string as the error message.");
|
||||
}
|
||||
}
|
||||
if (!sema_analyse_expr_of_required_type(context, type_bool, expr, false)) return false;
|
||||
if (expr->expr_kind == EXPR_TRY_UNWRAP_CHAIN)
|
||||
{
|
||||
if (!sema_analyse_try_unwrap_chain(context, expr)) return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!sema_analyse_expr_of_required_type(context, type_bool, expr, false)) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
43
test/test_suite/errors/try_unwrap_using_assert.c3t
Normal file
43
test/test_suite/errors/try_unwrap_using_assert.c3t
Normal file
@@ -0,0 +1,43 @@
|
||||
// #target: x64-darwin
|
||||
module test;
|
||||
|
||||
extern func int! maybe();
|
||||
|
||||
func int tester(int n)
|
||||
{
|
||||
int! num = maybe();
|
||||
assert(try num, "Hello");
|
||||
int x = num;
|
||||
return num;
|
||||
}
|
||||
|
||||
// #expect: test.ll
|
||||
|
||||
define i32 @test.tester(i32 %0) #0 {
|
||||
entry:
|
||||
%n = alloca i32, align 4
|
||||
%num = alloca i32, align 4
|
||||
%num.f = alloca i64, align 8
|
||||
%retparam = alloca i32, align 4
|
||||
%x = alloca i32, align 4
|
||||
store i32 %0, i32* %n, align 4
|
||||
%1 = call i64 @maybe(i32* %retparam)
|
||||
%not_err = icmp eq i64 %1, 0
|
||||
br i1 %not_err, label %after.errcheck, label %error
|
||||
|
||||
error: ; preds = %entry
|
||||
store i64 %1, i64* %num.f, align 8
|
||||
br label %after_assign
|
||||
|
||||
after.errcheck: ; preds = %entry
|
||||
%2 = load i32, i32* %retparam, align 4
|
||||
store i32 %2, i32* %num, align 4
|
||||
store i64 0, i64* %num.f, align 8
|
||||
br label %after_assign
|
||||
|
||||
after_assign: ; preds = %after.errcheck, %error
|
||||
%3 = load i32, i32* %num, align 4
|
||||
store i32 %3, i32* %x, align 4
|
||||
%4 = load i32, i32* %num, align 4
|
||||
ret i32 %4
|
||||
}
|
||||
Reference in New Issue
Block a user