From 81b29200e74c8e5f24923858bac6ffa38a2484aa Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Wed, 7 Oct 2015 19:22:01 -0400 Subject: [PATCH] fix #922 (wrong line numbers in error expressions) and remove old hacks around this issue --- src/builtins.c | 6 ------ src/cgutils.cpp | 14 +++++-------- src/codegen.cpp | 52 ++++++++++++++++++----------------------------- src/julia.h | 3 --- src/task.c | 5 ----- test/backtrace.jl | 3 ++- 6 files changed, 27 insertions(+), 56 deletions(-) diff --git a/src/builtins.c b/src/builtins.c index 0dd497981bc6a6..6fd90d141a5133 100644 --- a/src/builtins.c +++ b/src/builtins.c @@ -103,12 +103,6 @@ void NORETURN jl_type_error_rt(const char *fname, const char *context, jl_throw(ex); } -void NORETURN jl_type_error_rt_line(const char *fname, const char *context, - jl_value_t *ty, jl_value_t *got, int line) -{ - jl_type_error_rt(fname, context, ty, got); -} - void NORETURN jl_type_error(const char *fname, jl_value_t *expected, jl_value_t *got) { jl_type_error_rt(fname, "", expected, got); diff --git a/src/cgutils.cpp b/src/cgutils.cpp index 7f0d2c5046bb31..dade30965558f9 100644 --- a/src/cgutils.cpp +++ b/src/cgutils.cpp @@ -935,11 +935,9 @@ static void raise_exception_unless(Value *cond, Value *exc, jl_codectx_t *ctx) builder.CreateCondBr(cond, passBB, failBB); builder.SetInsertPoint(failBB); #ifdef LLVM37 - builder.CreateCall(prepare_call(jlthrow_line_func), { exc, - ConstantInt::get(T_int32, ctx->lineno) }); + builder.CreateCall(prepare_call(jlthrow_func), { exc }); #else - builder.CreateCall2(prepare_call(jlthrow_line_func), exc, - ConstantInt::get(T_int32, ctx->lineno)); + builder.CreateCall(prepare_call(jlthrow_func), exc); #endif builder.CreateUnreachable(); ctx->f->getBasicBlockList().push_back(passBB); @@ -983,13 +981,11 @@ static void emit_type_error(const jl_cgval_t &x, jl_value_t *type, const std::st #ifdef LLVM37 builder.CreateCall(prepare_call(jltypeerror_func), { fname_val, msg_val, - literal_pointer_val(type), boxed(x,ctx), - ConstantInt::get(T_int32, ctx->lineno) }); + literal_pointer_val(type), boxed(x,ctx)}); #else - builder.CreateCall5(prepare_call(jltypeerror_func), + builder.CreateCall4(prepare_call(jltypeerror_func), fname_val, msg_val, - literal_pointer_val(type), boxed(x,ctx), - ConstantInt::get(T_int32, ctx->lineno)); + literal_pointer_val(type), boxed(x,ctx)); #endif } diff --git a/src/codegen.cpp b/src/codegen.cpp index 3e88bdfc56bf0c..2894f650058df5 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -315,7 +315,6 @@ extern RTDyldMemoryManager* createRTDyldMemoryManagerOSX(); // important functions static Function *jlnew_func; static Function *jlthrow_func; -static Function *jlthrow_line_func; static Function *jlerror_func; static Function *jltypeerror_func; static Function *jlundefvarerror_func; @@ -539,7 +538,6 @@ typedef struct { bool vaStack; // varargs stack-allocated bool sret; int nReqArgs; - int lineno; std::vector boundsCheck; jl_gcinfo_t gc; @@ -1437,7 +1435,7 @@ extern "C" void jl_write_malloc_log(void) static void show_source_loc(JL_STREAM *out, jl_codectx_t *ctx) { if (ctx == NULL) return; - jl_printf(out, "in %s at %s:%d", ctx->linfo->name->name, ctx->linfo->file->name, ctx->lineno); + jl_printf(out, "in %s at %s", ctx->linfo->name->name, ctx->linfo->file->name); } extern "C" void jl_binding_deprecation_warning(jl_binding_t *b); @@ -4417,7 +4415,6 @@ static Function *emit_function(jl_lambda_info_t *lam) } } } - ctx.lineno = lno; int toplineno = lno; DIBuilder dbuilder(*m); @@ -4429,6 +4426,7 @@ static Function *emit_function(jl_lambda_info_t *lam) DIFile topfile; DISubprogram SP; #endif + DebugLoc inlineLoc; BasicBlock *b0 = BasicBlock::Create(jl_LLVMContext, "top", f); builder.SetInsertPoint(b0); @@ -4503,7 +4501,8 @@ static Function *emit_function(jl_lambda_info_t *lam) true, // isOptimized f); // Fn // set initial line number - builder.SetCurrentDebugLocation(DebugLoc::get(lno, 0, (MDNode*)SP, NULL)); + inlineLoc = DebugLoc::get(lno, 0, (MDNode*)SP, NULL); + builder.SetCurrentDebugLocation(inlineLoc); #ifndef LLVM37 assert(SP.Verify() && SP.describes(f) && SP.getFunction() == f); #endif @@ -4520,7 +4519,7 @@ static Function *emit_function(jl_lambda_info_t *lam) argname->name, // Variable name ctx.sret + i + 1, // Argument number (1-based) topfile, // File - ctx.lineno == -1 ? 0 : ctx.lineno, // Line + toplineno == -1 ? 0 : toplineno, // Line // Variable type julia_type_to_di(varinfo.value.typ,ctx.dbuilder,specsig)); #else @@ -4529,7 +4528,7 @@ static Function *emit_function(jl_lambda_info_t *lam) SP, // Scope (current function will be fill in later) argname->name, // Variable name topfile, // File - ctx.lineno == -1 ? 0 : ctx.lineno, // Line (for now, use lineno of the function) + toplineno == -1 ? 0 : toplineno, // Line (for now, use lineno of the function) julia_type_to_di(varinfo.value.typ, ctx.dbuilder, specsig), // Variable type false, // May be optimized out 0, // Flags (TODO: Do we need any) @@ -4543,7 +4542,7 @@ static Function *emit_function(jl_lambda_info_t *lam) ctx.vaName->name, // Variable name ctx.sret + nreq + 1, // Argument number (1-based) topfile, // File - ctx.lineno == -1 ? 0 : ctx.lineno, // Line (for now, use lineno of the function) + toplineno == -1 ? 0 : toplineno, // Line (for now, use lineno of the function) julia_type_to_di(ctx.vars[ctx.vaName].value.typ, ctx.dbuilder, false)); #else ctx.vars[ctx.vaName].dinfo = ctx.dbuilder->createLocalVariable( @@ -4551,7 +4550,7 @@ static Function *emit_function(jl_lambda_info_t *lam) SP, // Scope (current function will be fill in later) ctx.vaName->name, // Variable name topfile, // File - ctx.lineno == -1 ? 0 : ctx.lineno, // Line (for now, use lineno of the function) + toplineno == -1 ? 0 : toplineno, // Line (for now, use lineno of the function) julia_type_to_di(ctx.vars[ctx.vaName].value.typ, ctx.dbuilder, false), // Variable type false, // May be optimized out 0, // Flags (TODO: Do we need any) @@ -4572,7 +4571,7 @@ static Function *emit_function(jl_lambda_info_t *lam) SP, // Scope (current function will be fill in later) s->name, // Variable name topfile, // File - ctx.lineno == -1 ? 0 : ctx.lineno, // Line (for now, use lineno of the function) + toplineno == -1 ? 0 : toplineno, // Line (for now, use lineno of the function) julia_type_to_di(varinfo.value.typ, ctx.dbuilder, specsig), // Variable type false, // May be optimized out 0 // Flags (TODO: Do we need any) @@ -4596,7 +4595,7 @@ static Function *emit_function(jl_lambda_info_t *lam) SP, // Scope (current function will be filled in later) vname->name, // Variable name topfile, // File - ctx.lineno == -1 ? 0 : ctx.lineno, // Line (for now, use lineno of the function) + toplineno == -1 ? 0 : toplineno, // Line (for now, use lineno of the function) julia_type_to_di(varinfo.value.typ, ctx.dbuilder, specsig), // Variable type false, // May be optimized out 0 // Flags (TODO: Do we need any) @@ -4996,7 +4995,6 @@ static Function *emit_function(jl_lambda_info_t *lam) } DebugLoc loc; if (ctx.debug_enabled) { - MDNode *funcscope = (MDNode*)dbuilder.createLexicalBlockFile(SP, topfile); MDNode *scope; if ((dfil == topfile || dfil == NULL) && lno >= toplineno) @@ -5004,19 +5002,17 @@ static Function *emit_function(jl_lambda_info_t *lam) // for sequentially-defined code, // set location to line in top file. // TODO: improve handling of nested inlines - loc = DebugLoc::get(lno, 1, SP, NULL); + loc = inlineLoc = DebugLoc::get(lno, 1, SP, NULL); } else { // otherwise, we are compiling inlined code, // so set the DebugLoc "inlinedAt" parameter // to the current line, then use source loc. #ifdef LLVM37 scope = (MDNode*)dbuilder.createLexicalBlockFile(SP,dfil); - MDNode *inlineLocMd = DebugLoc::get(toplineno, 1, funcscope, NULL). - getAsMDNode(); + MDNode *inlineLocMd = inlineLoc.getAsMDNode(); #else scope = (MDNode*)dbuilder.createLexicalBlockFile(SP,DIFile(dfil)); - MDNode *inlineLocMd = DebugLoc::get(toplineno, 1, funcscope, NULL). - getAsMDNode(jl_LLVMContext); + MDNode *inlineLocMd = inlineLoc.getAsMDNode(jl_LLVMContext); #endif loc = DebugLoc::get(lno, 1, scope, inlineLocMd); } @@ -5024,7 +5020,6 @@ static Function *emit_function(jl_lambda_info_t *lam) } if (do_coverage) coverageVisitLine(filename, lno); - ctx.lineno = lno; // NOO TOUCHIE; NO TOUCH! See #922 } if (jl_is_labelnode(stmt)) { if (prevlabel) continue; @@ -5478,15 +5473,6 @@ static void init_julia_llvm_env(Module *m) jluboundserror_func->setDoesNotReturn(); add_named_global(jluboundserror_func, (void*)&jl_bounds_error_unboxed_int); - std::vector args2_throw(0); - args2_throw.push_back(T_pjlvalue); - args2_throw.push_back(T_int32); - jlthrow_line_func = - (Function*)m->getOrInsertFunction("jl_throw_with_superfluous_argument", - FunctionType::get(T_void, args2_throw, false)); - jlthrow_line_func->setDoesNotReturn(); - add_named_global(jlthrow_line_func, (void*)&jl_throw_with_superfluous_argument); - jlnew_func = Function::Create(jl_func_sig, Function::ExternalLinkage, "jl_new_structv", m); @@ -5517,13 +5503,12 @@ static void init_julia_llvm_env(Module *m) te_args.push_back(T_pint8); te_args.push_back(T_pjlvalue); te_args.push_back(T_pjlvalue); - te_args.push_back(T_int32); jltypeerror_func = Function::Create(FunctionType::get(T_void, te_args, false), Function::ExternalLinkage, - "jl_type_error_rt_line", m); + "jl_type_error_rt", m); jltypeerror_func->setDoesNotReturn(); - add_named_global(jltypeerror_func, (void*)&jl_type_error_rt_line); + add_named_global(jltypeerror_func, (void*)&jl_type_error_rt); std::vector args_2ptrs(0); args_2ptrs.push_back(T_pjlvalue); @@ -5923,13 +5908,16 @@ static void init_julia_llvm_env(Module *m) extern "C" void jl_init_codegen(void) { + const char *const argv_tailmerge[] = {"", "-enable-tail-merge=0"}; // NOO TOUCHIE; NO TOUCH! See #922 + cl::ParseCommandLineOptions(sizeof(argv_tailmerge)/sizeof(argv_tailmerge[0]), argv_tailmerge, "disable-tail-merge\n"); #if defined(_OS_WINDOWS_) && defined(_CPU_X86_64_) - const char *const argv[] = {"", "-disable-copyprop"}; // llvm bug 21743 - cl::ParseCommandLineOptions(sizeof(argv)/sizeof(argv[0]), argv, "disable-copyprop\n"); + const char *const argv_copyprop[] = {"", "-disable-copyprop"}; // llvm bug 21743 + cl::ParseCommandLineOptions(sizeof(argv_copyprop)/sizeof(argv_copyprop[0]), argv_copyprop, "disable-copyprop\n"); #endif #ifdef JL_DEBUG_BUILD cl::ParseEnvironmentOptions("Julia", "JULIA_LLVM_ARGS"); #endif + #if defined(_CPU_PPC_) || defined(_CPU_PPC64_) imaging_mode = true; // LLVM seems to JIT bad TOC tables for the optimizations we attempt in non-imaging_mode #else diff --git a/src/julia.h b/src/julia.h index ec05783766d701..43da2db6963c7e 100644 --- a/src/julia.h +++ b/src/julia.h @@ -1150,8 +1150,6 @@ DLLEXPORT void NORETURN jl_too_many_args(const char *fname, int max); DLLEXPORT void NORETURN jl_type_error(const char *fname, jl_value_t *expected, jl_value_t *got); DLLEXPORT void NORETURN jl_type_error_rt(const char *fname, const char *context, jl_value_t *ty, jl_value_t *got); -DLLEXPORT void NORETURN jl_type_error_rt_line(const char *fname, const char *context, - jl_value_t *ty, jl_value_t *got, int line); DLLEXPORT void NORETURN jl_undefined_var_error(jl_sym_t *var); DLLEXPORT void NORETURN jl_bounds_error(jl_value_t *v, jl_value_t *t); DLLEXPORT void NORETURN jl_bounds_error_v(jl_value_t *v, jl_value_t **idxs, size_t nidxs); @@ -1405,7 +1403,6 @@ extern DLLEXPORT JL_THREAD jl_value_t *jl_exception_in_transit; DLLEXPORT jl_task_t *jl_new_task(jl_function_t *start, size_t ssize); DLLEXPORT jl_value_t *jl_switchto(jl_task_t *t, jl_value_t *arg); DLLEXPORT void NORETURN jl_throw(jl_value_t *e); -DLLEXPORT void NORETURN jl_throw_with_superfluous_argument(jl_value_t *e, int); DLLEXPORT void NORETURN jl_rethrow(void); DLLEXPORT void NORETURN jl_rethrow_other(jl_value_t *e); diff --git a/src/task.c b/src/task.c index 31c3dc8b91085f..cf9f3715befdcc 100644 --- a/src/task.c +++ b/src/task.c @@ -828,11 +828,6 @@ DLLEXPORT void jl_rethrow_other(jl_value_t *e) throw_internal(e); } -DLLEXPORT void jl_throw_with_superfluous_argument(jl_value_t *e, int line) -{ - jl_throw(e); -} - DLLEXPORT jl_task_t *jl_new_task(jl_function_t *start, size_t ssize) { size_t pagesz = jl_page_size; diff --git a/test/backtrace.jl b/test/backtrace.jl index d5b9f3ad97c5fe..08908314f39f17 100644 --- a/test/backtrace.jl +++ b/test/backtrace.jl @@ -99,5 +99,6 @@ let ind2 = find(:test_throw_commoning .== map(b->code_loc(b)[1], b2)) @test !isempty(ind1) @test !isempty(ind2) - @test code_loc(b1[ind1[1]])[3] != code_loc(b2[ind2[1]])[3] + @test code_loc(b1[ind1[1]])[3] == code_loc(b2[ind2[1]])[3] && # source line, for example: essentials.jl:58 + code_loc(b1[ind1[1]])[5] != code_loc(b2[ind2[1]])[5] # inlined line, for example: backtrace.jl:82 end