Skip to content

Commit 656da33

Browse files
committed
ensure codegen normalizes BottomType to Type{Union{}}
otherwise, it can become confused why both Type{Union{}} and BottomType are both leaftypes that are not equal but are both accepted as the type of the constant singleton type object Union{} fix #20764
1 parent 589b399 commit 656da33

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
@@ -677,13 +677,41 @@ static inline jl_cgval_t ghostValue(jl_value_t *typ)
677677
{
678678
if (typ == jl_bottom_type)
679679
return jl_cgval_t(); // Undef{}
680+
if (typ == (jl_value_t*)jl_bottomtype_type) {
681+
// normalize BottomType to Type{Union{}}
682+
typ = (jl_value_t*)jl_wrap_Type(jl_bottom_type);
683+
}
684+
if (jl_is_type_type(typ)) {
685+
// replace T::Type{T} with T, by assuming that T must be a leaftype of some sort
686+
jl_cgval_t constant(NULL, NULL, true, typ, NULL);
687+
constant.constant = jl_tparam0(typ);
688+
return constant;
689+
}
680690
return jl_cgval_t(typ);
681691
}
682692
static inline jl_cgval_t ghostValue(jl_datatype_t *typ)
683693
{
684694
return ghostValue((jl_value_t*)typ);
685695
}
686696

697+
static inline jl_cgval_t mark_julia_const(jl_value_t *jv)
698+
{
699+
jl_value_t *typ;
700+
if (jl_is_type(jv)) {
701+
typ = (jl_value_t*)jl_wrap_Type(jv); // TODO: gc-root this?
702+
}
703+
else {
704+
typ = jl_typeof(jv);
705+
if (type_is_ghost(julia_type_to_llvm(typ))) {
706+
return ghostValue(typ);
707+
}
708+
}
709+
jl_cgval_t constant(NULL, NULL, true, typ, NULL);
710+
constant.constant = jv;
711+
return constant;
712+
}
713+
714+
687715
static inline jl_cgval_t mark_julia_slot(Value *v, jl_value_t *typ, Value *tindex, MDNode *tbaa)
688716
{
689717
// this enables lazy-copying of immutable values and stack or argument slots
@@ -700,11 +728,12 @@ static inline jl_cgval_t mark_julia_type(Value *v, bool isboxed, jl_value_t *typ
700728
// no need to explicitly load/store a constant/ghost value
701729
return ghostValue(typ);
702730
}
703-
if (jl_is_type_type(typ) && jl_is_leaf_type(jl_tparam0(typ))) {
704-
// replace T::Type{T} with T
705-
jl_cgval_t constant(NULL, NULL, true, typ, NULL);
706-
constant.constant = jl_tparam0(typ);
707-
return constant;
731+
if (jl_is_type_type(typ)) {
732+
jl_value_t *tp0 = jl_tparam0(typ);
733+
if (jl_is_leaf_type(tp0) || tp0 == jl_bottom_type) {
734+
// replace T::Type{T} with T
735+
return ghostValue(typ);
736+
}
708737
}
709738
Type *T = julia_type_to_llvm(typ);
710739
if (type_is_ghost(T)) {
@@ -733,7 +762,7 @@ static inline jl_cgval_t mark_julia_type(Value *v, bool isboxed, jl_datatype_t *
733762
// see if it might be profitable (and cheap) to change the type of v to typ
734763
static inline jl_cgval_t update_julia_type(const jl_cgval_t &v, jl_value_t *typ, jl_codectx_t *ctx)
735764
{
736-
if (v.typ == typ || v.typ == jl_bottom_type || jl_egal(v.typ, typ) || typ == (jl_value_t*)jl_any_type)
765+
if (v.typ == typ || v.typ == jl_bottom_type || v.constant || typ == (jl_value_t*)jl_any_type || jl_egal(v.typ, typ))
737766
return v; // fast-path
738767
if (jl_is_leaf_type(v.typ) && !jl_is_kind(v.typ)) {
739768
if (jl_is_leaf_type(typ) && !jl_is_kind(typ) && !((jl_datatype_t*)typ)->abstract && !((jl_datatype_t*)v.typ)->abstract) {
@@ -764,21 +793,6 @@ static inline jl_cgval_t update_julia_type(const jl_cgval_t &v, jl_value_t *typ,
764793
return jl_cgval_t(v, typ, NULL);
765794
}
766795

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

784798
static jl_sym_t *slot_symbol(int s, jl_codectx_t *ctx)
@@ -859,6 +873,8 @@ static void jl_rethrow_with_add(const char *fmt, ...)
859873
// given a value marked with type `v.typ`, compute the mapping and/or boxing to return a value of type `typ`
860874
static jl_cgval_t convert_julia_type(const jl_cgval_t &v, jl_value_t *typ, jl_codectx_t *ctx, bool needsroot = true)
861875
{
876+
if (typ == (jl_value_t*)jl_bottomtype_type)
877+
return ghostValue(typ); // normalize BottomType to Type{Union{}}
862878
if (v.typ == typ || v.typ == jl_bottom_type || jl_egal(v.typ, typ))
863879
return v; // fast-path
864880
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)