ccode: honor r2ghidra.casts instead of forcing casts off

ccode mode called setNoCastPrinting(true) after applying r2ghidra.casts, so
`e r2ghidra.casts=true` was silently overridden and semantically necessary
truncations disappeared. For

  long cast_test(long x) { return (long)(int)x + 0x100000000L; }

the output was `arg1 + 0x100000000`, which evaluates to 0xffffffff at
0xffffffff instead of the 0x1ffffffff the binary produces.

Let r2ghidra.casts decide: ccode keeps only the identifier cleanup and the
hidden implied ZEXT/SEXT extensions and no-convention prototype style. With
ccode=true,casts=true the printer now emits
`(int64_t)(int)arg1 + 0x100000000`; with casts=false it stays cast-free as the
option documents, and ccode=false output is unchanged.

Regression in test/db/extras/r2ghidra_ccode with the compiled fixture.
This commit is contained in:
Kirby Kuehl authored and pancake committed 2026-10-12 19:18:42 +02:00
1 parent c2c66513e1
commit 06db2a163c
4 files changed
+21 -3

No files matched your search

+4 -3
View File
@@ -233,11 +233,12 @@ static void Decompile(RCore *core, ut64 addr, DecompileMode mode, std::stringstr
bool showCasts = cfg_var_casts.GetBool (core->config);
r2c->setOptionNoCasts (!showCasts);
if (cfg_var_ccode.GetBool (core->config)) {
// CCODE-style output: no casts, hide implied ZEXT/SEXT extensions, drop the
// CCODE-style output: hide implied ZEXT/SEXT extensions and drop the
// calling convention from prototypes — closer to what Ghidra's toggleCCode
// emits and closer to plain standard C.
// emits and closer to plain standard C. Casts stay under the r2ghidra.casts
// option: forcing them off here would silently drop necessary truncations
// even when the user explicitly asked for them.
auto cc = dynamic_cast<PrintC *>(arch.print);
cc->setNoCastPrinting (true);
cc->setHideImpliedExts (true);
cc->setConvention (false);
}
+3
View File
@@ -0,0 +1,3 @@
// r2ghidra.ccode=true must not drop the (int) truncation, even when casts are
// explicitly requested with r2ghidra.casts=true.
long cast_test(long x) { return (long)(int)x + 0x100000000L; }
Binary file not shown.
+14
View File
@@ -39,3 +39,17 @@ EXPECT=<<EOF
__libc_init(param_1,0,*(iRam00000424 + 0x418),&stack0xffffffec);
EOF
RUN
NAME=ccode honors r2ghidra.casts and keeps necessary truncations
FILE=bins/elf/x86_64-cast-test.o
CMDS=<<EOF
aa
s sym.cast_test
e r2ghidra.ccode=true
e r2ghidra.casts=true
pdg~return
EOF
EXPECT=<<EOF
return (int64_t)(int)arg1 + 0x100000000;
EOF
RUN