Skip to content

[core] "Instruction removed from duplicated block ... please report this as an issue" on correct output #2904

Description

@obus-globus

Issue details

A short-circuit if (a || b) { ... } whose body is a shared block with two predecessors gets that block marked DUPLICATED (RegionMaker.java#L62-L64). When that block also holds a StringBuilder chain in the dex2jar/R8 idiom (the builder kept in a local and reloaded for each append, with the append return popped), the later string-concat simplification removes the now-redundant astore/aload/pop, and InsnRemover.remove emits Instruction removed from duplicated block: ..., please report this as an issue (InsnRemover.java#L224).

The decompiled output is correct; the warning is a false positive that tells users to report a bug. It shows only on .class input from dex2jar (R8 -> dex -> dex2jar), not on the original dex or on javac output, since only that path both shares the block (the ||) and reloads the builder through a local.

Sample

Java equivalent:

static String f(boolean a, boolean b, String s) {
    if (a || b) {
        s = s + ".mp4";
    }
    return s;
}

Minimal input, no Android tooling (Jasmin; .class/.jar build with dex2jar's bundled d2j-jasmin2jar.sh):

.method public static f(ZZLjava/lang/String;)Ljava/lang/String;
    iload 0
    ifne L0            ; a -> L0
    aload 2
    astore 3
    iload 1
    ifeq L1            ; !b -> skip
  L0:                  ; shared block, two predecessors
    new java/lang/StringBuilder
    dup
    invokespecial java/lang/StringBuilder/<init>()V
    astore 3           ; builder in a local (dex2jar idiom)
    aload 3
    aload 2
    invokevirtual java/lang/StringBuilder/append(Ljava/lang/String;)Ljava/lang/StringBuilder;
    pop
    aload 3
    ldc ".mp4"
    invokevirtual java/lang/StringBuilder/append(Ljava/lang/String;)Ljava/lang/StringBuilder;
    pop
    aload 3
    invokevirtual java/lang/StringBuilder/toString()Ljava/lang/String;
    astore 3
  L1:
    aload 3
    areturn
  .limit locals 4
  .limit stack 2
.end method

Output on master (8c28a85), correct code with two spurious warnings:

/* JADX WARN: Code duplicated, block: B:6:0x000a  */
/* JADX WARN: Instruction removed from duplicated block: B:6:0x000a, please report this as an issue */
public static String f(boolean z, boolean z2, String str) {
    String str2;
    if (z) {
        str2 = str + ".mp4";
    } else {
        str2 = str;
        if (z2) {
            str2 = str + ".mp4";
        }
    }
    return str2;
}

Found in a public app: com.rubenmayayo.reddit (Boost for Reddit) 1.12.12, method rb.FileCacheManager.getFileNameFromUrl (after running the APK through dex2jar).

Jadx version

master 8c28a85 (current HEAD)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions