Skip to content

bugc: copy structs and strings between storage and memory - #377

Merged
gnidan merged 6 commits into
mainfrom
bugc-struct-copies
Oct 9, 2026
Merged

gnidan merged 6 commits into
mainfrom
bugc-struct-copies

Conversation

@gnidan

@gnidan gnidan commented Oct 9, 2026

Copy link
Copy Markdown
Member

This lets a BUG program copy a struct from storage, change it in memory, and write it back, as Arcade does with let player: Player = players[msg.sender]; ... players[msg.sender] = player;, and gives a struct local a pointer to its fields.

It fixes two silent miscompiles:

  • let m: string = motd; loaded the slot's word and used it as a memory address. A string or bytes read from storage as a whole is now copied to memory: the length, then the data, from either the short (in-slot) or long (from keccak256(slot)) encoding.
  • players[msg.sender] = player; wrote the struct's memory address into one slot. A struct in memory assigned to storage is now written field by field, each packed into its bytes in its slot, and a string or bytes field is copied as Solidity encodes it, with the old value's unused data words cleared (as in bugc: clear unused data words when a storage string shrinks #370).

Also:

  • A struct copied from storage to memory may now have string and bytes fields (each field's word holds the address of its own copy). Nested structs copy recursively in both directions.
  • A struct field of a struct in storage now takes all of its struct's slots. Before, it took one, so a multi-slot nested struct overlapped the fields after it.
  • Copying an array between storage and memory is now a compile error. Before, it compiled to a copy of the slot's word.
  • A struct local's pointer is a group: the local's word, then each field's region in its word in memory (player-score, a scalar right-aligned), and for a string field its word plus nested player-name-length and player-name-data regions, the length read from memory. The locals soundness test resolves it with @ethdebug/pointers at every step of a real trace, at every optimization level.

@gnidan
gnidan force-pushed the bugc-struct-copies branch from 95607a5 to 5043a0f Compare October 9, 2026 05:09
@github-actions

github-actions Bot commented Oct 9, 2026 •

Copy link
Copy Markdown
Contributor
PR Preview Action v1.8.1
Preview removed because the pull request was closed.
2026-10-09 05:57 UTC

@gnidan
gnidan merged commit a086986 into main Oct 9, 2026
8 checks passed
@gnidan
gnidan deleted the bugc-struct-copies branch October 9, 2026 05:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant