@@ -516,7 +516,7 @@ static void typeassert_input(jl_codectx_t &ctx, const jl_cgval_t &jvinfo, jl_val
516516 ctx.builder .CreateCondBr (istype, passBB, failBB);
517517
518518 ctx.builder .SetInsertPoint (failBB);
519- emit_type_error (ctx, mark_julia_type (ctx, vx, true , jl_any_type), boxed (ctx, jlto_runtime), msg);
519+ just_emit_type_error (ctx, mark_julia_type (ctx, vx, true , jl_any_type), boxed (ctx, jlto_runtime), msg);
520520 ctx.builder .CreateUnreachable ();
521521 ctx.builder .SetInsertPoint (passBB);
522522 }
@@ -568,8 +568,15 @@ typedef struct {
568568 jl_value_t *gcroot;
569569} native_sym_arg_t ;
570570
571+ static inline const char *invalid_symbol_err_msg (bool ccall)
572+ {
573+ return ccall ?
574+ " ccall: first argument not a pointer or valid constant expression" :
575+ " cglobal: first argument not a pointer or valid constant expression" ;
576+ }
577+
571578// --- parse :sym or (:sym, :lib) argument into address info ---
572- static void interpret_symbol_arg (jl_codectx_t &ctx, native_sym_arg_t &out, jl_value_t *arg, const char *fname , bool llvmcall)
579+ static void interpret_symbol_arg (jl_codectx_t &ctx, native_sym_arg_t &out, jl_value_t *arg, bool ccall , bool llvmcall)
573580{
574581 Value *&jl_ptr = out.jl_ptr ;
575582 void (*&fptr)(void ) = out.fptr ;
@@ -599,9 +606,7 @@ static void interpret_symbol_arg(jl_codectx_t &ctx, native_sym_arg_t &out, jl_va
599606 jl_cgval_t arg1 = emit_expr (ctx, arg);
600607 jl_value_t *ptr_ty = arg1.typ ;
601608 if (!jl_is_cpointer_type (ptr_ty)) {
602- const char *errmsg = !strcmp (fname, " ccall" ) ?
603- " ccall: first argument not a pointer or valid constant expression" :
604- " cglobal: first argument not a pointer or valid constant expression" ;
609+ const char *errmsg = invalid_symbol_err_msg (ccall);
605610 emit_cpointercheck (ctx, arg1, errmsg);
606611 }
607612 arg1 = update_julia_type (ctx, arg1, (jl_value_t *)jl_voidpointer_type);
@@ -647,19 +652,14 @@ static void interpret_symbol_arg(jl_codectx_t &ctx, native_sym_arg_t &out, jl_va
647652 f_name = jl_symbol_name ((jl_sym_t *)t0);
648653 else if (jl_is_string (t0))
649654 f_name = jl_string_data (t0);
650- else
651- JL_TYPECHKS (fname, symbol, t0);
652655
653656 jl_value_t *t1 = jl_fieldref (ptr, 1 );
654657 if (jl_is_symbol (t1))
655658 f_lib = jl_symbol_name ((jl_sym_t *)t1);
656659 else if (jl_is_string (t1))
657660 f_lib = jl_string_data (t1);
658661 else
659- JL_TYPECHKS (fname, symbol, t1);
660- }
661- else {
662- JL_TYPECHKS (fname, pointer, ptr);
662+ f_name = NULL ;
663663 }
664664 }
665665}
@@ -696,7 +696,15 @@ static jl_cgval_t emit_cglobal(jl_codectx_t &ctx, jl_value_t **args, size_t narg
696696 Type *lrt = ctx.types ().T_size ;
697697 assert (lrt == julia_type_to_llvm (ctx, rt));
698698
699- interpret_symbol_arg (ctx, sym, args[1 ], " cglobal" , false );
699+ interpret_symbol_arg (ctx, sym, args[1 ], /* ccall=*/ false , false );
700+
701+ if (sym.f_name == NULL && sym.fptr == NULL && sym.jl_ptr == NULL && sym.gcroot != NULL ) {
702+ const char *errmsg = invalid_symbol_err_msg (/* ccall=*/ false );
703+ jl_cgval_t arg1 = emit_expr (ctx, args[1 ]);
704+ emit_type_error (ctx, arg1, literal_pointer_val (ctx, (jl_value_t *)jl_pointer_type), errmsg);
705+ JL_GC_POP ();
706+ return jl_cgval_t ();
707+ }
700708
701709 if (sym.jl_ptr != NULL ) {
702710 res = ctx.builder .CreateBitCast (sym.jl_ptr , lrt);
@@ -1346,14 +1354,20 @@ static jl_cgval_t emit_ccall(jl_codectx_t &ctx, jl_value_t **args, size_t nargs)
13461354 bool llvmcall = false ;
13471355 std::tie (cc, llvmcall) = convert_cconv (cc_sym);
13481356
1349- interpret_symbol_arg (ctx, symarg, args[1 ], " ccall" , llvmcall);
1357+ interpret_symbol_arg (ctx, symarg, args[1 ], /* ccall= */ true , llvmcall);
13501358 Value *&jl_ptr = symarg.jl_ptr ;
13511359 void (*&fptr)(void ) = symarg.fptr ;
13521360 const char *&f_name = symarg.f_name ;
13531361 const char *&f_lib = symarg.f_lib ;
13541362
13551363 if (f_name == NULL && fptr == NULL && jl_ptr == NULL ) {
1356- emit_error (ctx, " ccall: null function pointer" );
1364+ if (symarg.gcroot != NULL ) { // static_eval(ctx, args[1]) could not be interpreted to a function pointer
1365+ const char *errmsg = invalid_symbol_err_msg (/* ccall=*/ true );
1366+ jl_cgval_t arg1 = emit_expr (ctx, args[1 ]);
1367+ emit_type_error (ctx, arg1, literal_pointer_val (ctx, (jl_value_t *)jl_pointer_type), errmsg);
1368+ } else {
1369+ emit_error (ctx, " ccall: null function pointer" );
1370+ }
13571371 JL_GC_POP ();
13581372 return jl_cgval_t ();
13591373 }
0 commit comments