diff --git a/src/compiler/llvm_codegen_stmt.c b/src/compiler/llvm_codegen_stmt.c index 3c7f6e70e..94ca04414 100644 --- a/src/compiler/llvm_codegen_stmt.c +++ b/src/compiler/llvm_codegen_stmt.c @@ -1588,7 +1588,7 @@ void llvm_emit_panic_if_true(GenContext *c, BEValue *value, const char *panic_na { if (LLVMIsAConstantInt(value->value)) { - ASSERT(!LLVMConstIntGetZExtValue(value->value) && "Unexpected bounds check failed."); + ASSERT_AT(loc, !LLVMConstIntGetZExtValue(value->value) && "Unexpected bounds check failed."); return; } LLVMBasicBlockRef panic_block = llvm_basic_block_new(c, "panic"); diff --git a/src/compiler/sema_expr.c b/src/compiler/sema_expr.c index d2d81d193..4e96d38f3 100644 --- a/src/compiler/sema_expr.c +++ b/src/compiler/sema_expr.c @@ -143,8 +143,8 @@ static bool sema_binary_is_expr_lvalue(SemaContext *context, Expr *top_expr, Exp static void sema_binary_unify_voidptr(Expr *left, Expr *right, Type **left_type_ref, Type **right_type_ref); // -- function helper functions -static inline bool sema_expr_analyse_var_call(SemaContext *context, Expr *expr, Type *func_ptr_type, - bool optional, bool *no_match_ref); +static inline bool sema_expr_analyse_var_call(SemaContext *context, Expr *expr, Expr *var, + Type *func_ptr_type, bool optional,bool *no_match_ref); static inline bool sema_expr_analyse_func_call(SemaContext *context, Expr *expr, Decl *decl, Expr *struct_var, bool optional, bool *no_match_ref); @@ -2386,7 +2386,7 @@ SKIP_CONTRACTS: return true; } -static inline bool sema_expr_analyse_var_call(SemaContext *context, Expr *expr, Type *func_ptr_type, bool optional, bool *no_match_ref) +static inline bool sema_expr_analyse_var_call(SemaContext *context, Expr *expr, Expr *var, Type *func_ptr_type, bool optional,bool *no_match_ref) { func_ptr_type = type_flat_distinct_inline(func_ptr_type); if (func_ptr_type->type_kind != TYPE_FUNC_PTR) @@ -2399,6 +2399,10 @@ static inline bool sema_expr_analyse_var_call(SemaContext *context, Expr *expr, RETURN_SEMA_ERROR(expr, "Only macros, functions and function pointers may be invoked, this is of type '%s'.", type_to_error_string(func_ptr_type)); } + if (sema_cast_const(var) && expr_is_const_pointer(var) && var->const_expr.ptr == 0) + { + RETURN_SEMA_ERROR(var, "You cannot call a null function pointer."); + } Type *pointee = func_ptr_type->pointer; expr->call_expr.is_pointer_call = true; return sema_call_analyse_func_invocation(context, pointee->function.decl, pointee, expr, NULL, optional, @@ -3129,9 +3133,9 @@ bool sema_expr_analyse_general_call(SemaContext *context, Expr *expr, Decl *decl expr->call_expr.is_type_method = struct_var != NULL; if (decl == NULL) { - return sema_expr_analyse_var_call(context, expr, - type_flatten(exprptr(expr->call_expr.function)->type), optional, - no_match_ref); + Expr *var = exprptr(expr->call_expr.function); + return sema_expr_analyse_var_call(context, expr, var, type_flatten(var->type), + optional, no_match_ref); } if (!sema_analyse_decl(context, decl)) return false; switch (decl->decl_kind) @@ -3141,9 +3145,14 @@ bool sema_expr_analyse_general_call(SemaContext *context, Expr *expr, Decl *decl expr->call_expr.is_func_ref = true; return sema_expr_analyse_macro_call(context, expr, struct_var, decl, optional, no_match_ref); case DECL_VAR: + { ASSERT_SPAN(expr, struct_var == NULL); - return sema_expr_analyse_var_call(context, expr, decl->type->canonical, optional || IS_OPTIONAL(decl), - no_match_ref); + Expr *var = exprptr(expr->call_expr.function); + ASSERT_SPAN(expr, var); + return sema_expr_analyse_var_call(context, expr, var, decl->type->canonical, + optional || IS_OPTIONAL(decl), no_match_ref); + + } case DECL_FUNC: expr->call_expr.func_ref = declid(decl); expr->call_expr.is_func_ref = true;