From 84c1be48e253d2e5bb044744bf37d83c51568b9c 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 (cherry picked from commit af81d6c7fe09f57ab268ccd731bc2d2f4aee9a95) ref #13491 --- 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 8495f0261a746..f1a3d6dd538e5 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 b169bf3e0f4d7..db0cb7daf2b7a 100644 --- a/src/cgutils.cpp +++ b/src/cgutils.cpp @@ -1059,11 +1059,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); @@ -1107,13 +1105,11 @@ static void emit_type_error(Value *x, jl_value_t *type, const std::string &msg, #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 a890a8ea51e1a..a4657c09269de 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -300,7 +300,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; @@ -470,7 +469,6 @@ typedef struct { bool vaStack; // varargs stack-allocated bool sret; int nReqArgs; - int lineno; std::vector boundsCheck; jl_gcinfo_t gc; @@ -1274,7 +1272,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); @@ -4191,7 +4189,6 @@ static Function *emit_function(jl_lambda_info_t *lam) } } } - ctx.lineno = lno; int toplineno = lno; DIBuilder dbuilder(*m); @@ -4203,6 +4200,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); @@ -4283,7 +4281,8 @@ static Function *emit_function(jl_lambda_info_t *lam) f); // Function #endif // set initial line number - builder.SetCurrentDebugLocation(DebugLoc::get(lno, 0, (MDNode*)SP, NULL)); + inlineLoc = DebugLoc::get(lno, 0, (MDNode*)SP, NULL); + builder.SetCurrentDebugLocation(inlineLoc); #ifdef LLVM38 f->setSubprogram(SP); #endif @@ -4303,7 +4302,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.declType,ctx.dbuilder,specsig)); #else @@ -4312,7 +4311,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.declType,ctx.dbuilder,specsig), // Variable type false, // May be optimized out 0, // Flags (TODO: Do we need any) @@ -4326,7 +4325,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].declType,ctx.dbuilder,false)); #else ctx.vars[ctx.vaName].dinfo = ctx.dbuilder->createLocalVariable( @@ -4334,7 +4333,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].declType,ctx.dbuilder,false), // Variable type false, // May be optimized out 0, // Flags (TODO: Do we need any) @@ -4355,7 +4354,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.declType,ctx.dbuilder,specsig), // Variable type false, // May be optimized out 0 // Flags (TODO: Do we need any) @@ -4379,7 +4378,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.declType,ctx.dbuilder,specsig), // Variable type false, // May be optimized out 0 // Flags (TODO: Do we need any) @@ -4745,7 +4744,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) @@ -4753,19 +4751,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); } @@ -4773,7 +4769,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; @@ -5214,15 +5209,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(jl_pvalue_llvmt); - 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); @@ -5253,13 +5239,12 @@ static void init_julia_llvm_env(Module *m) te_args.push_back(T_pint8); te_args.push_back(jl_pvalue_llvmt); te_args.push_back(jl_pvalue_llvmt); - 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(jl_pvalue_llvmt); @@ -5701,13 +5686,16 @@ static inline SmallVector getTargetFeatures() { 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 bb923e3884bea..eb919373a92ac 100644 --- a/src/julia.h +++ b/src/julia.h @@ -1154,8 +1154,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); @@ -1409,7 +1407,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 99e8ac9647191..f2cde6166ae61 100644 --- a/src/task.c +++ b/src/task.c @@ -836,11 +836,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 d5b9f3ad97c5f..4f6b2eb6d194b 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]::Int == code_loc(b2[ind2[1]])[3]::Int && # source line, for example: essentials.jl:58 + code_loc(b1[ind1[1]])[5]::Int != code_loc(b2[ind2[1]])[5]::Int # inlined line, for example: backtrace.jl:82 end