Skip to content

Commit b53d6f2

Browse files
authored
Merge pull request #20884 from JuliaLang/jn/20764
ensure codegen normalizes BottomType to Type{Union{}}
2 parents 015cc63 + 656da33 commit b53d6f2

File tree

2 files changed

+42
-21
lines changed

2 files changed

+42
-21
lines changed

src/codegen.cpp

Lines changed: 37 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -673,13 +673,41 @@ static inline jl_cgval_t ghostValue(jl_value_t *typ)
673673
{
674674
if (typ == jl_bottom_type)
675675
return jl_cgval_t(); // Undef{}
676+
if (typ == (jl_value_t*)jl_bottomtype_type) {
677+
// normalize BottomType to Type{Union{}}
678+
typ = (jl_value_t*)jl_wrap_Type(jl_bottom_type);
679+
}
680+
if (jl_is_type_type(typ)) {
681+
// replace T::Type{T} with T, by assuming that T must be a leaftype of some sort
682+
jl_cgval_t constant(NULL, NULL, true, typ, NULL);
683+
constant.constant = jl_tparam0(typ);
684+
return constant;
685+
}
676686
return jl_cgval_t(typ);
677687
}
678688
static inline jl_cgval_t ghostValue(jl_datatype_t *typ)
679689
{
680690
return ghostValue((jl_value_t*)typ);
681691
}
682692

693+
static inline jl_cgval_t mark_julia_const(jl_value_t *jv)
694+
{
695+
jl_value_t *typ;
696+
if (jl_is_type(jv)) {
697+
typ = (jl_value_t*)jl_wrap_Type(jv); // TODO: gc-root this?
698+
}
699+
else {
700+
typ = jl_typeof(jv);
701+
if (type_is_ghost(julia_type_to_llvm(typ))) {
702+
return ghostValue(typ);
703+
}
704+
}
705+
jl_cgval_t constant(NULL, NULL, true, typ, NULL);
706+
constant.constant = jv;
707+
return constant;
708+
}
709+
710+
683711
static inline jl_cgval_t mark_julia_slot(Value *v, jl_value_t *typ, Value *tindex, MDNode *tbaa)
684712
{
685713
// this enables lazy-copying of immutable values and stack or argument slots
@@ -696,11 +724,12 @@ static inline jl_cgval_t mark_julia_type(Value *v, bool isboxed, jl_value_t *typ
696724
// no need to explicitly load/store a constant/ghost value
697725
return ghostValue(typ);
698726
}
699-
if (jl_is_type_type(typ) && jl_is_leaf_type(jl_tparam0(typ))) {
700-
// replace T::Type{T} with T
701-
jl_cgval_t constant(NULL, NULL, true, typ, NULL);
702-
constant.constant = jl_tparam0(typ);
703-
return constant;
727+
if (jl_is_type_type(typ)) {
728+
jl_value_t *tp0 = jl_tparam0(typ);
729+
if (jl_is_leaf_type(tp0) || tp0 == jl_bottom_type) {
730+
// replace T::Type{T} with T
731+
return ghostValue(typ);
732+
}
704733
}
705734
Type *T = julia_type_to_llvm(typ);
706735
if (type_is_ghost(T)) {
@@ -729,7 +758,7 @@ static inline jl_cgval_t mark_julia_type(Value *v, bool isboxed, jl_datatype_t *
729758
// see if it might be profitable (and cheap) to change the type of v to typ
730759
static inline jl_cgval_t update_julia_type(const jl_cgval_t &v, jl_value_t *typ, jl_codectx_t *ctx)
731760
{
732-
if (v.typ == typ || v.typ == jl_bottom_type || jl_egal(v.typ, typ) || typ == (jl_value_t*)jl_any_type)
761+
if (v.typ == typ || v.typ == jl_bottom_type || v.constant || typ == (jl_value_t*)jl_any_type || jl_egal(v.typ, typ))
733762
return v; // fast-path
734763
if (jl_is_leaf_type(v.typ) && !jl_is_kind(v.typ)) {
735764
if (jl_is_leaf_type(typ) && !jl_is_kind(typ) && !((jl_datatype_t*)typ)->abstract && !((jl_datatype_t*)v.typ)->abstract) {
@@ -760,21 +789,6 @@ static inline jl_cgval_t update_julia_type(const jl_cgval_t &v, jl_value_t *typ,
760789
return jl_cgval_t(v, typ, NULL);
761790
}
762791

763-
static inline jl_cgval_t mark_julia_const(jl_value_t *jv)
764-
{
765-
jl_value_t *typ;
766-
if (jl_is_type(jv))
767-
typ = (jl_value_t*)jl_wrap_Type(jv); // TODO: gc-root this?
768-
else
769-
typ = jl_typeof(jv);
770-
if (type_is_ghost(julia_type_to_llvm(typ))) {
771-
return ghostValue(typ);
772-
}
773-
jl_cgval_t constant(NULL, NULL, true, typ, NULL);
774-
constant.constant = jv;
775-
return constant;
776-
}
777-
778792
// --- allocating local variables ---
779793

780794
static jl_sym_t *slot_symbol(int s, jl_codectx_t *ctx)
@@ -855,6 +869,8 @@ static void jl_rethrow_with_add(const char *fmt, ...)
855869
// given a value marked with type `v.typ`, compute the mapping and/or boxing to return a value of type `typ`
856870
static jl_cgval_t convert_julia_type(const jl_cgval_t &v, jl_value_t *typ, jl_codectx_t *ctx, bool needsroot = true)
857871
{
872+
if (typ == (jl_value_t*)jl_bottomtype_type)
873+
return ghostValue(typ); // normalize BottomType to Type{Union{}}
858874
if (v.typ == typ || v.typ == jl_bottom_type || jl_egal(v.typ, typ))
859875
return v; // fast-path
860876
Type *T = julia_type_to_llvm(typ);

test/core.jl

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4755,3 +4755,8 @@ end
47554755
x::Vector{S}
47564756
y::Vector{T}
47574757
end
4758+
4759+
let a = Array{Core.BottomType, 1}(2)
4760+
@test a[1] == Union{}
4761+
@test a == [Union{}, Union{}]
4762+
end

0 commit comments

Comments
 (0)