Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A false negative about the rule BC_IMPOSSIBLE_DOWNCAST_OF_TOARRAY #1759

Open
Zustin opened this issue Oct 21, 2021 · 9 comments
Open

A false negative about the rule BC_IMPOSSIBLE_DOWNCAST_OF_TOARRAY #1759

Zustin opened this issue Oct 21, 2021 · 9 comments
Labels

Comments

@Zustin
Copy link
Contributor

Zustin commented Oct 21, 2021

SpotBugs Version: 4.4.2
Rule: BC_IMPOSSIBLE_DOWNCAST_OF_TOARRAY

Hi! I find a false negative about this rule. SpotBugs should have reported a warning at line 4. This program can lead to a running exception.

Code Sample

ArrayList<Integer> lst = new ArrayList<Integer>();
Integer[] res;
public Integer[] asArray() {
    res = (Integer[]) ((Object[])(lst.toArray()));  // should report a warning here
    return this.res;
}

Expected outcome:
SpotBugs should report a violation at line 4, but doesn't. This is a false-negative.

Running SpotBugs through: [CLI]

@KengoTODA
Copy link
Member

SpotBugs surely detects this problem. I made a test case in this commit d280e0f.

@Zustin
Copy link
Contributor Author

Zustin commented Oct 24, 2021

Hi, @KengoTODA. I have re-tested this case, but Spotbugs indeed doesn't report this bug. I run spotbugs by CLI and the command is

spotbugs -textui -effort:max -xml:withMessages -output ./result.xml case.class

The testing result file is here.
Could you please kindly help me check it or point out the problem? Thanks.

@KengoTODA
Copy link
Member

could you share a full
mcve project? At least not only report file but also build script, java code, and the JDK you use.

@Zustin
Copy link
Contributor Author

Zustin commented Oct 25, 2021

@KengoTODA Hi Kengo, thanks for your reply. I have created a repo for reproducing this issue. Link is here. Thanks!

@KengoTODA
Copy link
Member

Thanks. I confirmed that the BC_IMPOSSIBLE_DOWNCAST_OF_TOARRAY is reported as expected. So if you have a different result in your local, you probably have environmental problems.

Screen Shot 2021-10-25 at 19 20 05

My javac version is 11.0.11, AdoptOpenJDK-11.0.11+9.

@Zustin
Copy link
Contributor Author

Zustin commented Oct 25, 2021

@KengoTODA Hi, Kengo! I have tested this case by javac 11.0.11 and javac 1.8.0_171. Other environment variables are identical. And...SpotBugs can report this bug! This seems very interesting and I think it may be caused by different java versions. I am testing it with more java versions.

@KengoTODA
Copy link
Member

It seems that the class file built with Java 8 has an additional checkcast bytecode:

checkcast     #6                  // class "[Ljava/lang/Object;"

If we delete the cast (Object[]) in the code, Java 8 can pass the test too.

Bytecode built with Java 11

  public java.lang.Integer[] asArray();
    descriptor: ()[Ljava/lang/Integer;
    flags: (0x0001) ACC_PUBLIC
    Code:
      stack=2, locals=1, args_size=1
         0: aload_0
         1: aload_0
         2: getfield      #4                  // Field lst:Ljava/util/ArrayList;
         5: invokevirtual #5                  // Method java/util/ArrayList.toArray:()[Ljava/lang/Object;
         8: checkcast     #6                  // class "[Ljava/lang/Integer;"
        11: putfield      #7                  // Field res:[Ljava/lang/Integer;
        14: aload_0
        15: getfield      #7                  // Field res:[Ljava/lang/Integer;
        18: areturn
      LineNumberTable:
        line 12: 0
        line 13: 14
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0      19     0  this   LghIssues/Issue1759;

Bytecode built with Java 8

Use AdoptOpenJDK (build 1.8.0_292-b10) to build the class:

  public java.lang.Integer[] asArray();
    descriptor: ()[Ljava/lang/Integer;
    flags: ACC_PUBLIC
    Code:
      stack=2, locals=1, args_size=1
         0: aload_0
         1: aload_0
         2: getfield      #4                  // Field lst:Ljava/util/ArrayList;
         5: invokevirtual #5                  // Method java/util/ArrayList.toArray:()[Ljava/lang/Object;
         8: checkcast     #6                  // class "[Ljava/lang/Object;"
        11: checkcast     #7                  // class "[Ljava/lang/Integer;"
        14: putfield      #8                  // Field res:[Ljava/lang/Integer;
        17: aload_0
        18: getfield      #8                  // Field res:[Ljava/lang/Integer;
        21: areturn
      LineNumberTable:
        line 12: 0
        line 13: 17
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0      22     0  this   LghIssues/Issue1759;
}

@KengoTODA KengoTODA reopened this Oct 25, 2021
@KengoTODA
Copy link
Member

AdoptOpenJDK (build 10.0.2+13) can pass the test too. So javac behavior has been changed at Java 9 or 10.

@Zustin
Copy link
Contributor Author

Zustin commented Oct 26, 2021

Hi Kengo, I have tested Java 9 by this JDK (Link), Spotbugs can report this problem, so javac behavior may change at Java 9.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants