lifting-bits / rellic

Rellic produces goto-free C output from LLVM bitcode
Apache License 2.0
532 stars 43 forks source link

Rellic produces semantically non-equivalent code #325

Open vmihalko opened 1 year ago

vmihalko commented 1 year ago
Used version:

0.2.3. (current)

Reproducer:
#include <stdio.h>
int main(int argc, const char** argv) {
    int i = argc;
    if ( i == 1 ) { // no args
        putchar(4 + '0');
        i += 1;
        goto n5;    
    }
    if ( i > 1 ) { // args
        putchar( 5 + '0');
        goto n7;
    }
n5:
    putchar( 6 + '0');
n7:
    putchar( 7 + '0');
}
Steps to reproduce:
clang error.c -o error
clang error.c -S -emit-llvm -o error.ll
rellic-decomp --input error.ll --output de-error.c
clang de-error.c -o de-error
Expected behavior:

Executing error results in: "467"

Current behavior:

But executing de-error results in: "47"

Rellics output:
int main(int arg0, char **arg1);
unsigned int putchar(unsigned int arg0);
int main(int arg0, char **arg1) {
    unsigned int var0;
    unsigned int var1;
    char **var2;
    unsigned int var3;
    var0 = 0U;
    var1 = arg0;
    var2 = arg1;
    var3 = var1;
    if (var3 != 1U && (int)var3 > 1) {
        putchar(53U);
    }
    if (var3 == 1U) {
        putchar(52U);
        var3 = var3 + 1U;
    }
    if (var3 == 1U || (int)var3 <= 1) {
        putchar(54U);
    }
    putchar(55U);
    return var0;
}
frabert commented 1 year ago

Can reproduce 👍