summaryrefslogtreecommitdiff
path: root/src/ir
diff options
context:
space:
mode:
Diffstat (limited to 'src/ir')
-rw-r--r--src/ir/gc-type-utils.h12
-rw-r--r--src/ir/module-utils.cpp2
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);