High chrome Type Confusion 📄 Reporter bug report 🔧 Commit mapped

Overview

High
Severity
CVSS
No
Exploited ITW
Fixed
Fix Status
ImpactType Confusion in V8
DescriptionType Confusion in V8
ComponentV8
Bug ClassType Confusion
Tracker495679730
Fix commitc1e78b455e32 (v8/v8) +13/-2
CISA KEVNot listed
CreditedGoogle
Disclosed2026-04-07

Files Changed

  • src/maglev/maglev-graph-builder.cc
From c1e78b455e3224e286914b5ac241fbea064cb51d Mon Sep 17 00:00:00 2001
From: Darius Mercadier <dmercadier@chromium.org>
Date: Thu, 26 Mar 2026 10:36:49 +0100
Subject: [PATCH] [maglev] Account for phi smi type widening in BuildCheckHeapObject

Bug: 495679730
Change-Id: Icecb844aac559f2de15ac4ec3065ab1df6fb0585
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/7701796
Reviewed-by: Leszek Swirski <leszeks@chromium.org>
Commit-Queue: Leszek Swirski <leszeks@chromium.org>
Auto-Submit: Darius Mercadier <dmercadier@chromium.org>
Cr-Commit-Position: refs/heads/main@{#106058}
---

diff --git a/src/maglev/maglev-graph-builder.cc b/src/maglev/maglev-graph-builder.cc
index d7a31c2..5bff3e6 100644
--- a/src/maglev/maglev-graph-builder.cc
+++ b/src/maglev/maglev-graph-builder.cc
@@ -4196,8 +4196,8 @@
 ReduceResult MaglevGraphBuilder::BuildCheckHeapObject(ValueNode* object) {
   // Check for the empty type first so that we catch the case where
   // GetType(object) is already empty.
-  if (IsEmptyNodeType(
-          IntersectType(GetType(object), NodeType::kAnyHeapObject))) {
+  NodeType initial_type = GetType(object);
+  if (IsEmptyNodeType(IntersectType(initial_type, NodeType::kAnyHeapObject))) {
     return EmitUnconditionalDeopt(DeoptimizeReason::kSmi);
   }
   if (Phi* phi = object->TryCast<Phi>()) {
@@ -4208,6 +4208,17 @@
     phi->SetUseRequiresHeapObject();
   }
   if (EnsureType(object, NodeType::kAnyHeapObject)) return ReduceResult::Done();
+  if (object->Is<Phi>() && NodeTypeCanBe(initial_type, NodeType::kSmi)) {
+    // If {initial_type} contains kSmi, then phi untagging could widen this to a
+    // HeapNumber. Since the `EnsureType(.. kAnyHeapObject)` above just removed
+    // `kSmi` from the type, we need to make sure that still don't forget that
+    // HeapNumber is actually still a possibility.
+    // TODO(dmercadier): this is only a small band-aid: actually, any
+    // GetType(phi) could return Smi when the actual type ends up being
+    // HeapNumber.
+    NodeInfo* info = GetOrCreateInfoFor(object);
+    info->UnionType(NodeType::kHeapNumber);
+  }
   return AddNewNode<CheckHeapObject>({object});
 }
 
Loading diff…

Original Bug Report

reported by ma...@chromium.org

Phi untagging invalidates BuildCheckHeapObject's type refinement

Splitting from https://issues.chromium.org/u/1/issues/495149864#comment17 because this might be a separate bug.

Repro:

let o = { x : "abc" };
o.x = []; // Making non-string, non-const, but still HeapObject

function foo(c1, c2) {
  let phi1 = c1 ? 42 : 0x40000000;
  phi1 + 1; // inserting smi check

  let phi2 = c2 ? true : phi1;
  o.x = phi2;
}

%PrepareFunctionForOptimization(foo);
foo(true, true);
foo(true, true);

%OptimizeMaglevOnNextCall(foo);
foo(true, true);
foo(true, true);

foo(false, false);

with flags –allow-natives-syntax –maglev-untagged-phis –maglev-assert-types

Failure:

CheckMaglevType failed
DebugPrint: 0xf9e0104b685: [HeapNumber]
 - map: 0x0f9e00000515 <Map[12](HEAP_NUMBER_TYPE)>
 - value: 1073741824.0
0xf9e00000515: [Map] in ReadOnlySpace
 - map: 0x0f9e00000475 <MetaMap (0x0f9e0000002d <null>)>
 - type: HEAP_NUMBER_TYPE
 - instance size: 12
 - elements kind: HOLEY_ELEMENTS
 - enum length: invalid
 - stable_map
 - non-extensible
 - back pointer: 0x0f9e00000011 <undefined>
 - prototype_validity_cell: 0
 - instance descriptors (own) #0: 0x0f9e0000080d <DescriptorArray[0]>
 - prototype: 0x0f9e0000002d <null>
 - constructor: 0x0f9e0000002d <null>
 - dependent code: 0x0f9e000007f5 <Other heap object (WEAK_ARRAY_LIST_TYPE)>
 - construction counter: 0

Expected type: : DebugPrint: Smi: 0x10 (16)

Actual type: : DebugPrint: Smi: 0x2 (2)
View on issue tracker