Open pglizniewicz opened 5 years ago
As another point on clarity/consistency, similar compare instructions decompile into expressions with differing ordering of their operands. In the above example, the first and last CMP EDX have swapped operands in the decompile - one puts the constant on the left of the expression, the other on the right.
There are some that believe any constant of an "if" expression should be on the left, as it helps catch accidental use of assignment instead of equality. But either way, the decompiled output above is inconsistent.
(Figured it might be better to camp onto this bug instead of essentially duplicating most of it.)
Here is a similar issue. Consider the following:
typedef struct {
unsigned int n;
unsigned int **r;
}S;
extern void init(unsigned int *x);
void foo(S *p) {
int i;
for(i=0; i<p->n; i++)
init(p->r[i]);
}
On Ubuntu 16.04 X86 64 bit, gcc 5.4 -O3 turns the loop into (this from objdump):
18: 49 8b 44 24 08 mov 0x8(%r12),%rax
1d: 83 c3 01 add $0x1,%ebx
20: 48 8b 3c 28 mov (%rax,%rbp,1),%rdi
24: 48 83 c5 08 add $0x8,%rbp
28: e8 00 00 00 00 callq 2d <foo+0x2d>
2d: 41 39 1c 24 cmp %ebx,(%r12)
31: 77 e5 ja 18 <foo+0x18>
(The compiler turns the loop into if(p->n!=0)do{...}while(i<p->n);
)
The Ghidra 9.0.1 decompiler turns the condition of the test/branch at the bottom of the loop into uVar2 <= *puParm1 && *puParm1 != uVar2
(I've dropped the casts.) This amounts to turning the loop condition into i<=p->n && p->n != i.
(Here uVar2
is i
and puParam1
is p
.)
I had to stare at this for a while to convince myself that it was correct.
I think a better way to handle this is to allow interactively inverting the if conditions.
There are some that believe any constant of an "if" expression should be on the left, as it helps catch accidental use of assignment instead of equality. But either way, the decompiled output above is inconsistent.
I think this should never be done, any modern compiler flags this as an error. Yoda conditions are less readable. Also since this is decompiler output it won't get it wrong anyway...
I agree, please change -1 < voltage into voltage > -1
I agree that this is still an issue. (Ghidra 11.1)
Changing conditions to equivalent ones generates a decompiler output which is harder to understand. For example this:
was decompiled to:
}
In assembly, the variable was compared to the constant using less-equal, but in the decompile it's compared to the constant+1 using less. It's correct, but the resulting decompile is harder to understand. This code dealt with setting bit-depth of the screen and while a 8-bit bit-depth was meaningful, 9-bit bit-depth feels out of place in this context.
Ghidra should either use the same operation as in assembly or allow us to choose it via something like the "Convert" option for constants in the "Listing" view.