openjdk/jdk · critical

error: node is null

Error message

error: node is null

What it means

ArchDesc::buildMList internal check: a null MatchRule node reached the list builder ('error: node is null'). buildMList is invoked with node == nullptr from a caller that should always pass a child rule; note the code already dereferences node->_opType above for the index lookup, so in practice the preceding lookup crash/error usually fires first — this message marks a structural inconsistency in the match-rule tree built by the parser.

Source

Thrown at src/hotspot/share/adlc/archDesc.cpp:559

  leftstr = rightstr = nullptr;
  // Do not process leaves of the Match Tree if they are not ideal
  if ((node) && (node->_lChild == nullptr) && (node->_rChild == nullptr) &&
      ((form = (Form *)_globalNames[node->_opType]) != nullptr) &&
      (!form->ideal_only())) {
    return;
  }

  // Identify index position among ideal operands
  intptr_t index = _last_opcode;
  const char *indexStr = node ? node->_opType : (char *) " ";
  index = (intptr_t)_idealIndex[indexStr];
  if (index == 0) {
    fprintf(stderr, "error: operand \"%s\" not found\n", indexStr);
    assert(0, "fatal error");
  }

  if (node == nullptr) {
    fprintf(stderr, "error: node is null\n");
    assert(0, "fatal error");
  }
  // Build MatchLists for children
  // Check each child for an internal operand name, and use that name
  // for the parent's matchlist entry if it exists
  mnode = node->_lChild;
  if (mnode) {
    buildMList(mnode, nullptr, nullptr, nullptr, nullptr);
    leftstr = mnode->_internalop ? mnode->_internalop : mnode->_opType;
  }
  mnode = node->_rChild;
  if (mnode) {
    buildMList(mnode, nullptr, nullptr, nullptr, nullptr);
    rightstr = mnode->_internalop ? mnode->_internalop : mnode->_opType;
  }
  // Grab the string for the opcode of this list entry
  if (rootOp == nullptr) {
    opcode = (node->_internalop) ? node->_internalop : node->_opType;

View on GitHub (pinned to 88dfb74bbe)

Solutions

  1. Fix the syntax/operand errors reported earlier in the log first; this message is usually secondary
  2. Check the flagged instruction's match rule has a well-formed '( result operand )' tree with both children present
  3. Restore the rule from a known-good revision and reapply the edit
Defensive patterns

Strategy: validation

Validate before calling

make adlc 2>&1 | grep -cE 'syntax error|operand .* not found' # nonzero => fix primary errors; 'node is null' is secondary

Prevention

When it happens

Trigger: A malformed or truncated match rule (parser produced a rule with missing children), or ADLC caller logic passing null where a child rule was expected (buildMList(mnode, ...) recursion with an absent child).

Common situations: Editing match-rule nesting by hand and dropping a child operand; .ad merge conflicts leaving a half-formed rule; almost always accompanied by [94] or a syntax error that is the true cause.

Related errors


AI-assisted analysis of openjdk/jdk@88dfb74bbe (2026-08-14). Data as JSON: /api/errors/968e28a2b7f943f8. Report an issue: GitHub.