Repository navigation
Commit 492bcb5
converter: fix the printf argument/cast misalignment, and refuse loudly on a structured binding
printf casts were taken from the wrong slot, which is why `printf("%c")` printed
a numeric value -- a symptom recorded in AGENT-COMMON for a while and now
root-caused. Two independent bugs in the same alignment:
1. `if (types[j]) StrCat(kAs, types[j++]);` advanced `j` ONLY on a non-null
entry. `types` is parallel to the VARIADIC ARGUMENTS -- printf2fmt pushes one
entry per conversion that consumes an argument, and a null entry means "pass
through, no cast" -- so every pass-through conversion PINNED `j` and the next
cast-needing conversion took its cast from the wrong slot. Measured on
`printf("%d %c\n", 65, 'B')`: the `%d` entry is null, `j` stayed 0, and the
`u8 as char` cast from the `%c` slot was applied to the FIRST argument. It
compiled and printed the wrong values. The index is now `i - first`, with a
bounds check so more arguments than conversions gets no cast rather than an
out-of-bounds read.
2. `case '%'` pushed a `types` entry, but `%%` is a literal percent and consumes
NO argument, so it shifted every later argument by one on its own.
73cfd28 had made (1) more reachable: its survey arm pushes a null entry for an
unknown specifier, so `%f` followed by `%c` under --survey hits it too.
Verified byte-exact against clang after the fix, both models: C++ `65 B`,
unsafe MATCH, refcount MATCH; and the `%%` case `100% B`.
ReportUnsupportedStructuredBinding: the same NDEBUG silent-omission class as
73cfd28's exception fix, confirmed by measurement rather than by analogy. With
the pre-fix release binary a TU containing `auto [x, y] = p;` exited rc=0 and
the emitted Rust contained the following `println!` referring to `x` and `y`
while the declaration itself had VANISHED -- VisitVarDecl (converter.cpp:678)
returns false having emitted no text. Now report_fatal_error naming the
construct, its bindings and the location (rc=134); the pre-existing survey arm
still records and continues (rc=0, count=1).
Ranking note for the remaining asserts: standard Cpp2Rust#1 (NDEBUG-erased
non-termination) now has NO candidate. All 30 `assert(0` sites were scanned
mechanically for "last statement of a loop body with a non-advancing cursor" and
the printf loop fixed in 73cfd28 was the only one. Remaining sites are Cpp2Rust#2
(silent omission) and Cpp2Rust#3 (UB).
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>1 parent 8605102 commit 492bcb5
2 files changed
Lines changed: 35 additions & 7 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
3880 | 3880 | | |
3881 | 3881 | | |
3882 | 3882 | | |
3883 | | - | |
3884 | | - | |
| 3883 | + | |
| 3884 | + | |
| 3885 | + | |
| 3886 | + | |
| 3887 | + | |
| 3888 | + | |
| 3889 | + | |
| 3890 | + | |
3885 | 3891 | | |
3886 | 3892 | | |
3887 | 3893 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
999 | 999 | | |
1000 | 1000 | | |
1001 | 1001 | | |
1002 | | - | |
| 1002 | + | |
| 1003 | + | |
| 1004 | + | |
| 1005 | + | |
| 1006 | + | |
1003 | 1007 | | |
1004 | 1008 | | |
1005 | 1009 | | |
| |||
1127 | 1131 | | |
1128 | 1132 | | |
1129 | 1133 | | |
1130 | | - | |
1131 | | - | |
| 1134 | + | |
| 1135 | + | |
| 1136 | + | |
| 1137 | + | |
| 1138 | + | |
| 1139 | + | |
| 1140 | + | |
| 1141 | + | |
| 1142 | + | |
| 1143 | + | |
| 1144 | + | |
| 1145 | + | |
| 1146 | + | |
| 1147 | + | |
| 1148 | + | |
| 1149 | + | |
| 1150 | + | |
| 1151 | + | |
1132 | 1152 | | |
1133 | 1153 | | |
1134 | | - | |
1135 | | - | |
| 1154 | + | |
| 1155 | + | |
| 1156 | + | |
| 1157 | + | |
1136 | 1158 | | |
1137 | 1159 | | |
1138 | 1160 | | |
| |||
0 commit comments