Skip to content

[AUTOMATED] Preserve word bits through resolved union members - #1244

Merged
mahaloz merged 7 commits into
Noelo-Lab:mainfrom
thotypous:fix/implied-transfer-types
Oct 22, 2026
Merged

mahaloz merged 7 commits into
Noelo-Lab:mainfrom
thotypous:fix/implied-transfer-types

Conversation

@thotypous

Copy link
Copy Markdown
Contributor

An indexed word copy can become a numeric float conversion. A native input word of 1 then comes back as 1065353216 (1.0f bits).

cat > copy.c <<'C'
union block { float real[32]; unsigned integer[32]; } items;
__attribute__((naked)) unsigned transfer(unsigned index) {
 __asm__("movl 4(%esp),%eax; shll $2,%eax; movl _items(%eax),%edx;"
         "movl %edx,_items+64; flds _items+64; fstps _items+68;"
         "movl _items+64,%eax; retl");
}
C
clang --target=i686-w64-windows-gnu -O1 -c copy.c -o copy.obj
kuna decompile-project copy.obj -o output --option nanignore none \
 --option indexaliasguard full --option stackviews on \
 --assert 'typedef union block {float real[32];unsigned int integer[32];} block;' \
 --assert 'data 0x400028 block items' \
 --assert 'prototype _transfer unsigned int __cdecl transfer(unsigned int index)'
cat output/copy.obj.c

Before: items.real[0x10] = (unsigned int)items.integer[index];

  • Use the same operation-facing global member lookup for rendering and storage-transfer checks. The walk must report named union members as well as unnamed typed pieces.
  • Honor that resolved type for both CAST and COPY, keeping word copies as bit reinterpretations.

Tests cover PE32 and ELF64, strict Clang recompilation, and 4,096 native/regenerated ELF calls at each of -O0 and -O2.

@thotypous
thotypous marked this pull request as draft October 21, 2026 14:59
@thotypous

Copy link
Copy Markdown
Contributor Author

[AUTOMATED] Fixed the parity failure in 5a10955. Named frame-member type lookup now respects stackviews off, including temporary values whose variable group contains stack storage. Global-member resolution remains available independently.

The existing kuna-stacklifetimes-cfg.xml fixture passes all 12 assertions without changing expectations. The four focused bitcast integration tests and make check-spec also pass. The previous workspace CI job passed; both CI gates will rerun for this commit.

mahaloz and others added 3 commits October 22, 2026 18:47
…nsfer section

The CAST/COPY printed-type rule and the stackviews gate for named frame
members now sit with the Noelo-Lab#1230 named-member rule they extend, instead of a
detached paragraph at the end of the chapter.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BEr111CDLJsQMzY3YSyWXD
@mahaloz

mahaloz commented Oct 22, 2026

Copy link
Copy Markdown
Contributor

[AUTOMATED] Pushed two commits so this merges with current main:

Behavior is unchanged from 5a10955.

mahaloz and others added 2 commits October 22, 2026 20:24
Noelo-Lab#1231 removed the COPY member gate in storage_transfer, so every same-width
COPY is judged by its printed types; that subsumes this branch's printed-type
gate. Kept: printed member types for CAST as well as COPY, and the stackviews
gate for named frame members.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BEr111CDLJsQMzY3YSyWXD
@mahaloz
mahaloz merged commit 3fa148b into Noelo-Lab:main Oct 22, 2026
2 checks passed
mahaloz added a commit to thotypous/kuna that referenced this pull request Oct 22, 2026
Noelo-Lab#1244 landed as a squash; this re-applies only Noelo-Lab#1247's own changes on top
of main.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BEr111CDLJsQMzY3YSyWXD
mahaloz pushed a commit that referenced this pull request Oct 22, 2026
A byte-copy helper can turn an unaligned word copy into a numeric float conversion. A native input word of `1` then comes back as `1065353216` (`1.0f` bits).

```sh
cat > copy.c <<'C'
union block { float real[32]; unsigned integer[32]; } items;
__attribute__((naked)) unsigned transfer(unsigned index) {
 __asm__("movl 4(%esp),%eax; shll $2,%eax; movl _items+1(%eax),%edx;"
         "movl %edx,_items+64; flds _items+64; fstps _items+68;"
         "movl _items+64,%eax; retl");
}
C
clang --target=i686-w64-windows-gnu -O1 -c copy.c -o copy.obj
kuna decompile-project copy.obj -o output --option nanignore none \
 --option indexaliasguard full --option stackviews on \
 --assert 'typedef union block {float real[32];unsigned int integer[32];} block;' \
 --assert 'data 0x400028 block items' \
 --assert 'prototype _transfer unsigned int __cdecl transfer(unsigned int index)'
cat output/copy.obj.c
```

Before: `items.real[0x10] = *(unsigned int *)__builtin_memcpy(&(unsigned int){0}, ...);`

- A statement LOAD copies into a compound literal with the rendered destination member’s same-width scalar type.
- A STORE uses the rendered source member’s type for its compound initializer. Both paths preserve bytes instead of converting integer and float values.
- Builds on #1244’s operation-facing member lookup.

Tests cover PE32 and ELF64, union and float-only declarations, strict Clang recompilation at `-O0`/`-O2`, and native ELF return values plus all 128 backing bytes across 4,096 finite patterns per configuration.



Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BEr111CDLJsQMzY3YSyWXD
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.

2 participants