mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
- Crash when creating $Type* where $Type is an optional type #2848
- Crashes when using `io::EOF~!` in various unhandled places. #2848
This commit is contained in:
@@ -4452,7 +4452,7 @@ static inline void llvm_emit_force_unwrap_expr(GenContext *c, BEValue *be_value,
|
||||
POP_CATCH();
|
||||
|
||||
// Emit success and to end.
|
||||
llvm_emit_br(c, no_err_block);
|
||||
bool emit_no_err = llvm_emit_br(c, no_err_block);
|
||||
|
||||
POP_CATCH();
|
||||
|
||||
@@ -4469,8 +4469,11 @@ static inline void llvm_emit_force_unwrap_expr(GenContext *c, BEValue *be_value,
|
||||
vec_add(varargs, error_var_ref);
|
||||
llvm_emit_panic(c, "Force unwrap failed!", loc, "Unexpected fault '%s' was unwrapped!", varargs);
|
||||
}
|
||||
llvm_emit_block(c, no_err_block);
|
||||
EMIT_EXPR_LOC(c, expr);
|
||||
if (emit_no_err)
|
||||
{
|
||||
llvm_emit_block(c, no_err_block);
|
||||
EMIT_EXPR_LOC(c, expr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4614,6 +4617,7 @@ void gencontext_emit_ternary_expr(GenContext *c, BEValue *value, Expr *expr)
|
||||
Expr *cond = exprptr(expr->ternary_expr.cond);
|
||||
llvm_emit_expr(c, value, cond);
|
||||
llvm_value_rvalue(c, value);
|
||||
RETURN_ON_EMPTY_BLOCK(value);
|
||||
|
||||
Expr *else_expr = exprptr(expr->ternary_expr.else_expr);
|
||||
Expr *then_expr = exprptr(expr->ternary_expr.then_expr);
|
||||
@@ -5992,6 +5996,7 @@ static void llvm_emit_call_expr(GenContext *c, BEValue *result_value, Expr *expr
|
||||
{
|
||||
llvm_emit_expr(c, value_ref, arg);
|
||||
llvm_value_fold_optional(c, value_ref);
|
||||
RETURN_ON_EMPTY_BLOCK(result_value);
|
||||
continue;
|
||||
}
|
||||
Decl *decl = sig->params[i];
|
||||
@@ -5999,11 +6004,13 @@ static void llvm_emit_call_expr(GenContext *c, BEValue *result_value, Expr *expr
|
||||
if (vararg_splat)
|
||||
{
|
||||
llvm_emit_vasplat_expr(c, value_ref, vararg_splat, param);
|
||||
RETURN_ON_EMPTY_BLOCK(result_value);
|
||||
continue;
|
||||
}
|
||||
if (varargs)
|
||||
{
|
||||
llvm_emit_varargs_expr(c, value_ref, varargs, param);
|
||||
RETURN_ON_EMPTY_BLOCK(result_value);
|
||||
continue;
|
||||
}
|
||||
// Just set the size to zero.
|
||||
@@ -6017,6 +6024,7 @@ static void llvm_emit_call_expr(GenContext *c, BEValue *result_value, Expr *expr
|
||||
BEValue *value_ref = &values[arg_count + i];
|
||||
llvm_emit_expr(c, value_ref, vararg);
|
||||
llvm_value_fold_optional(c, value_ref);
|
||||
RETURN_ON_EMPTY_BLOCK(result_value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7016,10 +7024,12 @@ static void llvm_emit_make_any(GenContext *c, BEValue *value, Expr *expr)
|
||||
|
||||
llvm_emit_expr(c, value, expr->make_any_expr.inner);
|
||||
llvm_value_rvalue(c, value);
|
||||
RETURN_ON_EMPTY_BLOCK(value);
|
||||
BEValue typeid_val;
|
||||
Expr *typeid = expr->make_any_expr.typeid;
|
||||
llvm_emit_expr(c, &typeid_val, typeid);
|
||||
llvm_value_rvalue(c, &typeid_val);
|
||||
RETURN_ON_EMPTY_BLOCK(value);
|
||||
llvm_value_aggregate_two(c, value, expr->type, value->value, typeid_val.value);
|
||||
}
|
||||
|
||||
|
||||
@@ -594,8 +594,8 @@ void llvm_emit_debug_local_var(GenContext *c, Decl *var);
|
||||
#define EMIT_SPAN(c, x) do { if (c->debug.builder) llvm_emit_debug_location(c, x); } while (0)
|
||||
#define PUSH_DEFER_ERROR(val__) LLVMValueRef def_err__ = c->defer_error_var; c->defer_error_var = val__
|
||||
#define POP_DEFER_ERROR() c->defer_error_var = def_err__
|
||||
#define RETURN_ON_EMPTY_BLOCK(value__) do { if (!c->current_block) { llvm_value_set_empty(value__); return; }} while(0)
|
||||
#define RETURN_ON_EMPTY_BLOCK_VOID() do { if (!c->current_block) { return; }} while(0)
|
||||
#define RETURN_ON_EMPTY_BLOCK(value__) do { if (!llvm_is_global_eval(c) && !c->current_block) { llvm_value_set_empty(value__); return; }} while(0)
|
||||
#define RETURN_ON_EMPTY_BLOCK_VOID() do { if (!llvm_is_global_eval(c) && !c->current_block) { return; }} while(0)
|
||||
|
||||
LLVMAtomicOrdering llvm_atomic_ordering(Atomicity atomicity);
|
||||
|
||||
|
||||
@@ -3731,7 +3731,7 @@ static inline bool sema_call_analyse_member_set(SemaContext *context, Expr *expr
|
||||
}
|
||||
Expr *access = expr_new_expr(target_kind == TYPE_BITSTRUCT ? EXPR_BITACCESS : EXPR_ACCESS_RESOLVED, expr);
|
||||
access->access_resolved_expr = (ExprResolvedAccess) { .parent = inner, .ref = decl };
|
||||
access->type = decl->type;
|
||||
access->type = type_add_optional(decl->type, IS_OPTIONAL(inner));
|
||||
access->resolve_status = RESOLVE_DONE;
|
||||
expr->expr_kind = EXPR_BINARY;
|
||||
expr->binary_expr = (ExprBinary) { .left = exprid(access), .right = exprid(arg), .operator = BINARYOP_ASSIGN };
|
||||
@@ -3759,7 +3759,7 @@ static inline bool sema_call_analyse_member_get(SemaContext *context, Expr *expr
|
||||
}
|
||||
expr->expr_kind = target_kind == TYPE_BITSTRUCT ? EXPR_BITACCESS : EXPR_ACCESS_RESOLVED;
|
||||
expr->access_resolved_expr = (ExprResolvedAccess) { .parent = inner, .ref = decl };
|
||||
expr->type = decl->type;
|
||||
expr->type = type_add_optional(decl->type, IS_OPTIONAL(inner));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -122,7 +122,7 @@ static inline bool sema_analyse_assert_stmt(SemaContext *context, Ast *statement
|
||||
case STORAGE_NORMAL:
|
||||
break;
|
||||
case STORAGE_WILDCARD:
|
||||
UNREACHABLE
|
||||
RETURN_SEMA_ERROR(e, "This value is always rethrown and doesn't have a definite type. This is not valid.");
|
||||
case STORAGE_VOID:
|
||||
RETURN_SEMA_ERROR(e, "This expression is of type 'void', did you make a mistake?");
|
||||
case STORAGE_COMPILE_TIME:
|
||||
|
||||
@@ -99,6 +99,10 @@ bool sema_resolve_array_like_len(SemaContext *context, TypeInfo *type_info, Arra
|
||||
|
||||
static inline bool sema_check_array_type(SemaContext *context, TypeInfo *original_info, Type *base, TypeInfoKind kind, ArraySize len, Type **result_ref)
|
||||
{
|
||||
if (base->type_kind == TYPE_OPTIONAL)
|
||||
{
|
||||
RETURN_SEMA_ERROR(original_info, "You cannot form an array with an optional element type.");
|
||||
}
|
||||
Type *distinct_base = type_flatten(base);
|
||||
|
||||
if (type_is_infer_type(distinct_base))
|
||||
@@ -585,40 +589,37 @@ static inline bool sema_resolve_type(SemaContext *context, TypeInfo *type_info,
|
||||
if (!sema_resolve_ptr_type(context, type_info, resolve_kind)) return type_info_poison(type_info);
|
||||
break;
|
||||
}
|
||||
APPEND_QUALIFIERS:
|
||||
APPEND_QUALIFIERS:;
|
||||
Type *type = type_no_optional(type_info->type);
|
||||
switch (kind)
|
||||
{
|
||||
case TYPE_COMPRESSED_NONE:
|
||||
break;
|
||||
case TYPE_COMPRESSED_PTR:
|
||||
if (!sema_check_ptr_type(context, type_info, type_info->type)) return type_info_poison(type_info);
|
||||
type_info->type = type_get_ptr(type_info->type);
|
||||
if (!sema_check_ptr_type(context, type_info, type)) return type_info_poison(type_info);
|
||||
type = type_get_ptr(type);
|
||||
break;
|
||||
case TYPE_COMPRESSED_SUB:
|
||||
if (!sema_check_array_type(context, type_info, type_info->type, TYPE_INFO_SLICE, 0, &type_info->type)) return type_info_poison(type_info);
|
||||
if (!sema_check_array_type(context, type_info, type, TYPE_INFO_SLICE, 0, &type)) return type_info_poison(type_info);
|
||||
break;
|
||||
case TYPE_COMPRESSED_SUBPTR:
|
||||
if (!sema_check_array_type(context, type_info, type_info->type, TYPE_INFO_SLICE, 0, &type_info->type)) return type_info_poison(type_info);
|
||||
type_info->type = type_get_ptr(type_info->type);
|
||||
if (!sema_check_array_type(context, type_info, type, TYPE_INFO_SLICE, 0, &type)) return type_info_poison(type_info);
|
||||
type = type_get_ptr(type);
|
||||
break;
|
||||
case TYPE_COMPRESSED_PTRPTR:
|
||||
if (!sema_check_ptr_type(context, type_info, type_info->type)) return type_info_poison(type_info);
|
||||
type_info->type = type_get_ptr(type_get_ptr(type_info->type));
|
||||
if (!sema_check_ptr_type(context, type_info, type)) return type_info_poison(type_info);
|
||||
type = type_get_ptr(type_get_ptr(type));
|
||||
break;
|
||||
case TYPE_COMPRESSED_PTRSUB:
|
||||
if (!sema_check_ptr_type(context, type_info, type_info->type)) return type_info_poison(type_info);
|
||||
type_info->type = type_get_slice(type_get_ptr(type_info->type));
|
||||
if (!sema_check_ptr_type(context, type_info, type)) return type_info_poison(type_info);
|
||||
type = type_get_slice(type_get_ptr(type));
|
||||
break;
|
||||
case TYPE_COMPRESSED_SUBSUB:
|
||||
if (!sema_check_array_type(context, type_info, type_info->type, TYPE_INFO_SLICE, 0, &type_info->type)) return type_info_poison(type_info);
|
||||
type_info->type = type_get_slice(type_info->type);
|
||||
if (!sema_check_array_type(context, type_info, type, TYPE_INFO_SLICE, 0, &type)) return type_info_poison(type_info);
|
||||
type = type_get_slice(type);
|
||||
break;
|
||||
}
|
||||
if (type_info->optional)
|
||||
{
|
||||
Type *type = type_info->type;
|
||||
if (!type_is_optional(type)) type_info->type = type_get_optional(type);
|
||||
}
|
||||
type_info->type = type_add_optional(type, type_info->optional || type_is_optional(type_info->type));
|
||||
type_info->resolve_status = RESOLVE_DONE;
|
||||
return true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user