diff options
Diffstat (limited to 'src/ir')
-rw-r--r-- | src/ir/gc-type-utils.h | 12 | ||||
-rw-r--r-- | src/ir/module-utils.cpp | 2 |
2 files changed, 9 insertions, 5 deletions
diff --git a/src/ir/gc-type-utils.h b/src/ir/gc-type-utils.h index abe5f2dfc..5e3de37e5 100644 --- a/src/ir/gc-type-utils.h +++ b/src/ir/gc-type-utils.h @@ -52,16 +52,20 @@ inline EvaluationResult evaluateKindCheck(Expression* curr) { // We don't check nullability here. case BrOnNull: case BrOnNonNull: + return Unknown; case BrOnCastFail: flip = true; [[fallthrough]]; case BrOnCast: - // Note that the type must be non-nullable for us to succeed since a - // null would make us fail. - if (Type::isSubType(br->ref->type, - Type(br->intendedType, NonNullable))) { + // If we already have a subtype of the cast type, the cast will succeed. + if (Type::isSubType(br->ref->type, br->castType)) { return flip ? Failure : Success; } + // If the cast type is unrelated to the type we have, the cast will + // certainly fail. + if (!Type::isSubType(br->castType, br->ref->type)) { + return flip ? Success : Failure; + } return Unknown; case BrOnNonFunc: flip = true; diff --git a/src/ir/module-utils.cpp b/src/ir/module-utils.cpp index 0cdff0955..9dfc5f123 100644 --- a/src/ir/module-utils.cpp +++ b/src/ir/module-utils.cpp @@ -77,7 +77,7 @@ struct CodeScanner counts.note(cast->castType); } else if (auto* cast = curr->dynCast<BrOn>()) { if (cast->op == BrOnCast || cast->op == BrOnCastFail) { - counts.note(cast->intendedType); + counts.note(cast->castType); } } else if (auto* get = curr->dynCast<StructGet>()) { counts.note(get->ref->type); |