From 724b8c5b64f4451521e6c49e455aea4caf1c0058 Mon Sep 17 00:00:00 2001 From: oscarddssmith Date: Fri, 11 Oct 2024 15:51:11 -0400 Subject: [PATCH] fix error path --- src/cgutils.cpp | 15 +++++++++++---- src/codegen.cpp | 7 +++++++ src/julia.h | 1 + src/rtutils.c | 7 +++++++ 4 files changed, 26 insertions(+), 4 deletions(-) diff --git a/src/cgutils.cpp b/src/cgutils.cpp index eca23f06a9160d..833b3494fe2776 100644 --- a/src/cgutils.cpp +++ b/src/cgutils.cpp @@ -1602,19 +1602,24 @@ static void emit_error(jl_codectx_t &ctx, const Twine &txt) } // DO NOT PASS IN A CONST CONDITION! -static void error_unless(jl_codectx_t &ctx, Value *cond, const Twine &msg) +static void error_unless(jl_codectx_t &ctx, Function *F, Value *cond, const Twine &msg) { ++EmittedConditionalErrors; BasicBlock *failBB = BasicBlock::Create(ctx.builder.getContext(), "fail", ctx.f); BasicBlock *passBB = BasicBlock::Create(ctx.builder.getContext(), "pass"); ctx.builder.CreateCondBr(cond, passBB, failBB); ctx.builder.SetInsertPoint(failBB); - just_emit_error(ctx, prepare_call(jlerror_func), msg); + just_emit_error(ctx, F, msg); ctx.builder.CreateUnreachable(); passBB->insertInto(ctx.f); ctx.builder.SetInsertPoint(passBB); } +static void error_unless(jl_codectx_t &ctx, Value *cond, const Twine &msg) +{ + error_unless(ctx, prepare_call(jlerror_func), cond, msg); +} + static void raise_exception(jl_codectx_t &ctx, Value *exc, BasicBlock *contBB=nullptr) { @@ -4520,7 +4525,7 @@ static jl_cgval_t emit_const_len_memorynew(jl_codectx_t &ctx, jl_datatype_t *typ overflow |= __builtin_add_overflow(nbytes, nel, &nbytes); } if (overflow) - emit_error(ctx, "invalid GenericMemory size: too large for system address width"); + emit_error(ctx, prepare_call(jlargumenterror_func), "invalid GenericMemory size: too large for system address width"); auto ct = get_current_task(ctx); auto ptls = get_current_ptls(ctx); @@ -4636,8 +4641,10 @@ static jl_cgval_t emit_memorynew(jl_codectx_t &ctx, jl_datatype_t *typ, jl_cgval Value *overflow1 = ctx.builder.CreateExtractValue(add_with_overflow, 1); overflow = ctx.builder.CreateOr(overflow, overflow1); } + Value *negnel = ctx.builder.CreateICmpSLT(nel_unboxed, ConstantInt::get(T_size, 0)); + overflow = ctx.builder.CreateOr(overflow, negnel); Value *notoverflow = ctx.builder.CreateNot(overflow); - error_unless(ctx, notoverflow, "invalid GenericMemory size: too large for system address width"); + error_unless(ctx, prepare_call(jlargumenterror_func), notoverflow, "invalid GenericMemory size: too large for system address width"); // actually allocate auto call = prepare_call(jl_alloc_genericmemory_unchecked_func); auto alloc = ctx.builder.CreateCall(call, { ptls, nbytes, cg_typ}); diff --git a/src/codegen.cpp b/src/codegen.cpp index 05d3255d1c3840..328b16b75aad7f 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -820,6 +820,12 @@ static const auto jlerror_func = new JuliaFunction<>{ {getPointerTy(C)}, false); }, get_attrs_noreturn, }; +static const auto jlargumenterror_func = new JuliaFunction<>{ + XSTR(jl_argument_error), + [](LLVMContext &C) { return FunctionType::get(getVoidTy(C), + {getPointerTy(C)}, false); }, + get_attrs_noreturn, +}; static const auto jlatomicerror_func = new JuliaFunction<>{ XSTR(jl_atomic_error), [](LLVMContext &C) { return FunctionType::get(getVoidTy(C), @@ -10356,6 +10362,7 @@ static void init_jit_functions(void) add_named_global("__stack_chk_fail", &__stack_chk_fail); add_named_global(jlpgcstack_func, (void*)NULL); add_named_global(jlerror_func, &jl_error); + add_named_global(jlargumenterror_func, &jl_argument_error); add_named_global(jlatomicerror_func, &jl_atomic_error); add_named_global(jlthrow_func, &jl_throw); add_named_global(jlundefvarerror_func, &jl_undefined_var_error); diff --git a/src/julia.h b/src/julia.h index 1a6ffb6d35efb8..33cd4d3098728c 100644 --- a/src/julia.h +++ b/src/julia.h @@ -2064,6 +2064,7 @@ JL_DLLEXPORT void JL_NORETURN jl_type_error_rt(const char *fname, jl_value_t *got JL_MAYBE_UNROOTED); JL_DLLEXPORT void JL_NORETURN jl_undefined_var_error(jl_sym_t *var, jl_value_t *scope JL_MAYBE_UNROOTED); JL_DLLEXPORT void JL_NORETURN jl_has_no_field_error(jl_datatype_t *t, jl_sym_t *var); +JL_DLLEXPORT void JL_NORETURN jl_argument_error(char *str); JL_DLLEXPORT void JL_NORETURN jl_atomic_error(char *str); JL_DLLEXPORT void JL_NORETURN jl_bounds_error(jl_value_t *v JL_MAYBE_UNROOTED, jl_value_t *t JL_MAYBE_UNROOTED); diff --git a/src/rtutils.c b/src/rtutils.c index 85a9be5e0b1dae..c9aa4d29f31abf 100644 --- a/src/rtutils.c +++ b/src/rtutils.c @@ -157,6 +157,13 @@ JL_DLLEXPORT void JL_NORETURN jl_has_no_field_error(jl_datatype_t *t, jl_sym_t * jl_throw(jl_new_struct(jl_fielderror_type, t, var)); } +JL_DLLEXPORT void JL_NORETURN jl_argument_error(char *str) // == jl_exceptionf(jl_argumenterror_type, "%s", str) +{ + jl_value_t *msg = jl_pchar_to_string((char*)str, strlen(str)); + JL_GC_PUSH1(&msg); + jl_throw(jl_new_struct(jl_argumenterror_type, msg)); +} + JL_DLLEXPORT void JL_NORETURN jl_atomic_error(char *str) // == jl_exceptionf(jl_atomicerror_type, "%s", str) { jl_value_t *msg = jl_pchar_to_string((char*)str, strlen(str));