Skip to content

Commit d7fd339

Browse files
vtjnashXnartharax
authored andcommitted
more robust validation of allocation type (JuliaLang#49269)
We generally hit the runtime in pretty specific places when allocations look funky (because they are missing a typevar bound, so inference is not too willing to deal with it). Try to throw an error in those cases before those can get allocated and cause problems later from being non-concrete objects. Fix JuliaLang#49203
1 parent 9082065 commit d7fd339

File tree

3 files changed

+28
-15
lines changed

3 files changed

+28
-15
lines changed

src/datatype.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1400,6 +1400,9 @@ JL_DLLEXPORT jl_value_t *jl_new_struct(jl_datatype_t *type, ...)
14001400
{
14011401
jl_task_t *ct = jl_current_task;
14021402
if (type->instance != NULL) return type->instance;
1403+
if (!jl_is_datatype(type) || !type->isconcretetype || type->layout == NULL) {
1404+
jl_type_error("new", (jl_value_t*)jl_datatype_type, (jl_value_t*)type);
1405+
}
14031406
va_list args;
14041407
size_t i, nf = jl_datatype_nfields(type);
14051408
va_start(args, type);
@@ -1417,7 +1420,7 @@ JL_DLLEXPORT jl_value_t *jl_new_struct(jl_datatype_t *type, ...)
14171420
JL_DLLEXPORT jl_value_t *jl_new_structv(jl_datatype_t *type, jl_value_t **args, uint32_t na)
14181421
{
14191422
jl_task_t *ct = jl_current_task;
1420-
if (!jl_is_datatype(type) || type->layout == NULL) {
1423+
if (!jl_is_datatype(type) || !type->isconcretetype || type->layout == NULL) {
14211424
jl_type_error("new", (jl_value_t*)jl_datatype_type, (jl_value_t*)type);
14221425
}
14231426
size_t nf = jl_datatype_nfields(type);
@@ -1454,7 +1457,7 @@ JL_DLLEXPORT jl_value_t *jl_new_structt(jl_datatype_t *type, jl_value_t *tup)
14541457
jl_task_t *ct = jl_current_task;
14551458
if (!jl_is_tuple(tup))
14561459
jl_type_error("new", (jl_value_t*)jl_tuple_type, tup);
1457-
if (!jl_is_datatype(type) || type->layout == NULL)
1460+
if (!jl_is_datatype(type) || !type->isconcretetype || type->layout == NULL)
14581461
jl_type_error("new", (jl_value_t *)jl_datatype_type, (jl_value_t *)type);
14591462
size_t nargs = jl_nfields(tup);
14601463
size_t nf = jl_datatype_nfields(type);
@@ -1500,6 +1503,9 @@ JL_DLLEXPORT jl_value_t *jl_new_struct_uninit(jl_datatype_t *type)
15001503
{
15011504
jl_task_t *ct = jl_current_task;
15021505
if (type->instance != NULL) return type->instance;
1506+
if (!jl_is_datatype(type) || type->layout == NULL) {
1507+
jl_type_error("new", (jl_value_t*)jl_datatype_type, (jl_value_t*)type);
1508+
}
15031509
size_t size = jl_datatype_size(type);
15041510
jl_value_t *jv = jl_gc_alloc(ct->ptls, size, type);
15051511
if (size > 0)

src/intrinsics.cpp

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -504,20 +504,25 @@ static jl_cgval_t generic_bitcast(jl_codectx_t &ctx, const jl_cgval_t *argv)
504504
Type *llvmt = bitstype_to_llvm((jl_value_t*)bt, ctx.builder.getContext(), true);
505505
uint32_t nb = jl_datatype_size(bt);
506506

507+
Value *bt_value_rt = NULL;
508+
if (!jl_is_concrete_type((jl_value_t*)bt)) {
509+
bt_value_rt = boxed(ctx, bt_value);
510+
emit_concretecheck(ctx, bt_value_rt, "bitcast: target type not a leaf primitive type");
511+
}
512+
507513
// Examine the second argument //
508514
bool isboxed;
509515
Type *vxt = julia_type_to_llvm(ctx, v.typ, &isboxed);
510-
511516
if (!jl_is_primitivetype(v.typ) || jl_datatype_size(v.typ) != nb) {
512517
Value *typ = emit_typeof_boxed(ctx, v);
513518
if (!jl_is_primitivetype(v.typ)) {
514519
if (jl_is_datatype(v.typ) && !jl_is_abstracttype(v.typ)) {
515-
emit_error(ctx, "bitcast: expected primitive type value for second argument");
520+
emit_error(ctx, "bitcast: value not a primitive type");
516521
return jl_cgval_t();
517522
}
518523
else {
519524
Value *isprimitive = emit_datatype_isprimitivetype(ctx, typ);
520-
error_unless(ctx, isprimitive, "bitcast: expected primitive type value for second argument");
525+
error_unless(ctx, isprimitive, "bitcast: value not a primitive type");
521526
}
522527
}
523528
if (jl_is_datatype(v.typ) && !jl_is_abstracttype(v.typ)) {
@@ -570,7 +575,7 @@ static jl_cgval_t generic_bitcast(jl_codectx_t &ctx, const jl_cgval_t *argv)
570575
return mark_julia_type(ctx, vx, false, bt);
571576
}
572577
else {
573-
Value *box = emit_allocobj(ctx, nb, boxed(ctx, bt_value));
578+
Value *box = emit_allocobj(ctx, nb, bt_value_rt);
574579
init_bits_value(ctx, box, vx, ctx.tbaa().tbaa_immut);
575580
return mark_julia_type(ctx, box, true, bt->name->wrapper);
576581
}
@@ -624,7 +629,9 @@ static jl_cgval_t generic_cast(
624629
return mark_julia_type(ctx, ans, false, jlto);
625630
}
626631
else {
627-
Value *box = emit_allocobj(ctx, nb, boxed(ctx, targ));
632+
Value *targ_rt = boxed(ctx, targ);
633+
emit_concretecheck(ctx, targ_rt, std::string(jl_intrinsic_name(f)) + ": target type not a leaf primitive type");
634+
Value *box = emit_allocobj(ctx, nb, targ_rt);
628635
init_bits_value(ctx, box, ans, ctx.tbaa().tbaa_immut);
629636
return mark_julia_type(ctx, box, true, jlto->name->wrapper);
630637
}

src/runtime_intrinsics.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -717,7 +717,7 @@ SELECTOR_FUNC(intrinsic_1)
717717
#define un_iintrinsic(name, u) \
718718
JL_DLLEXPORT jl_value_t *jl_##name(jl_value_t *a) \
719719
{ \
720-
return jl_iintrinsic_1(jl_typeof(a), a, #name, u##signbitbyte, jl_intrinsiclambda_ty1, name##_list); \
720+
return jl_iintrinsic_1(a, #name, u##signbitbyte, jl_intrinsiclambda_ty1, name##_list); \
721721
}
722722
#define un_iintrinsic_fast(LLVMOP, OP, name, u) \
723723
un_iintrinsic_ctype(OP, name, 8, u##int##8_t) \
@@ -743,7 +743,7 @@ SELECTOR_FUNC(intrinsic_u1)
743743
#define uu_iintrinsic(name, u) \
744744
JL_DLLEXPORT jl_value_t *jl_##name(jl_value_t *a) \
745745
{ \
746-
return jl_iintrinsic_1(jl_typeof(a), a, #name, u##signbitbyte, jl_intrinsiclambda_u1, name##_list); \
746+
return jl_iintrinsic_1(a, #name, u##signbitbyte, jl_intrinsiclambda_u1, name##_list); \
747747
}
748748
#define uu_iintrinsic_fast(LLVMOP, OP, name, u) \
749749
uu_iintrinsic_ctype(OP, name, 8, u##int##8_t) \
@@ -765,14 +765,13 @@ static const select_intrinsic_u1_t name##_list = { \
765765
uu_iintrinsic(name, u)
766766

767767
static inline
768-
jl_value_t *jl_iintrinsic_1(jl_value_t *ty, jl_value_t *a, const char *name,
768+
jl_value_t *jl_iintrinsic_1(jl_value_t *a, const char *name,
769769
char (*getsign)(void*, unsigned),
770770
jl_value_t *(*lambda1)(jl_value_t*, void*, unsigned, unsigned, const void*), const void *list)
771771
{
772-
if (!jl_is_primitivetype(jl_typeof(a)))
773-
jl_errorf("%s: value is not a primitive type", name);
772+
jl_value_t *ty = jl_typeof(a);
774773
if (!jl_is_primitivetype(ty))
775-
jl_errorf("%s: type is not a primitive type", name);
774+
jl_errorf("%s: value is not a primitive type", name);
776775
void *pa = jl_data_ptr(a);
777776
unsigned isize = jl_datatype_size(jl_typeof(a));
778777
unsigned isize2 = next_power_of_two(isize);
@@ -833,11 +832,12 @@ JL_DLLEXPORT jl_value_t *jl_##name(jl_value_t *ty, jl_value_t *a) \
833832

834833
static inline jl_value_t *jl_intrinsic_cvt(jl_value_t *ty, jl_value_t *a, const char *name, intrinsic_cvt_t op)
835834
{
835+
JL_TYPECHKS(name, datatype, ty);
836+
if (!jl_is_concrete_type(ty) || !jl_is_primitivetype(ty))
837+
jl_errorf("%s: target type not a leaf primitive type", name);
836838
jl_value_t *aty = jl_typeof(a);
837839
if (!jl_is_primitivetype(aty))
838840
jl_errorf("%s: value is not a primitive type", name);
839-
if (!jl_is_primitivetype(ty))
840-
jl_errorf("%s: type is not a primitive type", name);
841841
void *pa = jl_data_ptr(a);
842842
unsigned isize = jl_datatype_size(aty);
843843
unsigned osize = jl_datatype_size(ty);

0 commit comments

Comments
 (0)