SystemVerilog OOP Mastery · All levels

Handle Aliasing Bugs: Code Examples

Code Examples for Handle Aliasing Bugs.

Code examples

Shallow copy of nested payload

systemverilog
class payload;\n  rand bit [7:0] bytes[];\nendclass\n\nclass txn;\n  rand bit [31:0] addr;\n  payload pld;\n\n  function new();\n    pld = new();\n  endfunction\n\n  function txn copy_bug();\n    txn c = new();\n    c.addr = this.addr;\n    // BUG: both txns share one payload object.\n    c.pld = this.pld;\n    return c;\n  endfunction\n\n  function txn copy_fix();\n    txn c = new();\n    c.addr = this.addr;\n    // FIX: deep-copy nested payload and dynamic array.\n    c.pld = new();\n    c.pld.bytes = new[this.pld.bytes.size()];\n    foreach (this.pld.bytes[i])\n      c.pld.bytes[i] = this.pld.bytes[i];\n    return c;\n  endfunction\nendclass

Top-level objects are distinct, but payload aliasing still couples them. Always inspect nested handles, not just parent handles.

Queue snapshot stores live handle

systemverilog
class tr;\n  int id;\nendclass\n\ntr exp_q[$];\ntr t = new();\nt.id = 10;\n\n// BUG: queue stores original handle, not a frozen snapshot.\nexp_q.push_back(t);\nt.id = 99;\n// exp_q[0].id is now 99, expected was silently rewritten.\n\nclass tr_fix extends tr;\n  function tr_fix clone();\n    tr_fix c = new();\n    c.id = this.id;\n    return c;\n  endfunction\nendclass\n\ntr_fix q2[$];\ntr_fix t2 = new();\nt2.id = 10;\n// FIX: push a clone so later edits do not back-write expected data.\nq2.push_back(t2.clone());\nt2.id = 99;

This pattern is common in scoreboards and predictor queues. Snapshot APIs should clone by default to make aliasing harder to introduce.

Related topics