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
CFGBuilderException when assigning double or long in groovy constructor #2145
Comments
Thanks for opening your first issue here! 😃 |
This modifies spotbugsTestCases/build.gradle to add Groovy support and cleans up / refactors the AbstractIntegrationTest to read .class files generated by the Groovy compiler. At the same time simplifies some logic and switches use of java.io.File over to the java.nio.file package instead.
This modifies spotbugsTestCases/build.gradle to add Groovy support and cleans up / refactors the AbstractIntegrationTest to read .class files generated by the Groovy compiler. At the same time simplifies some logic and switches use of java.io.File over to the java.nio.file package instead.
bytecode of Class1public class Class1 implements groovy/lang/GroovyObject { |
According to the
Next, point is that operands after the
How it changes operand stack depth? The answer is 2:
Then |
according to the following debug log: diff --git a/spotbugs/src/main/java/edu/umd/cs/findbugs/ba/BetterCFGBuilder2.java b/spotbugs/src/main/java/edu/umd/cs/findbugs/ba/BetterCFGBuilder2.java
index 734d9eed6..347383e2b 100644
--- a/spotbugs/src/main/java/edu/umd/cs/findbugs/ba/BetterCFGBuilder2.java
+++ b/spotbugs/src/main/java/edu/umd/cs/findbugs/ba/BetterCFGBuilder2.java
@@ -924,6 +924,19 @@ public class BetterCFGBuilder2 implements CFGBuilder, EdgeTypes, Debug {
}
}
+ private int countConsumedStack(Instruction inst) {
+ int consume = inst.consumeStack(cpg);
+ if (consume == Const.UNPREDICTABLE) {
+ throw new RuntimeException("unexpected consume for " + inst);
+ }
+ int produce = inst.produceStack(cpg);
+ if (produce == Const.UNPREDICTABLE) {
+ throw new RuntimeException("unexpected produce for " + inst);
+ }
+ System.err.printf("%s: stack size changed %d (produced %d, consumed %d)%n", inst, produce - consume, produce, consume);
+ return consume - produce;
+ }
+
/**
* Add exception edges for given instruction.
*
@@ -1010,6 +1023,7 @@ public class BetterCFGBuilder2 implements CFGBuilder, EdgeTypes, Debug {
if (ins instanceof PUTFIELD && !methodGen.isStatic()) {
// Assume that PUTFIELD on this object is not PEI
int depth = ins.consumeStack(cpg);
+ StringBuilder sb = new StringBuilder().append('\n').append(handle).append(" (depth:").append(depth).append(')');
for (InstructionHandle prev = handle.getPrev(); prev != null; prev = prev.getPrev()) {
Instruction prevInst = prev.getInstruction();
if (prevInst instanceof BranchInstruction) {
@@ -1027,9 +1041,10 @@ public class BetterCFGBuilder2 implements CFGBuilder, EdgeTypes, Debug {
return true;
}
}
- depth = depth - prevInst.produceStack(cpg) + prevInst.consumeStack(cpg);
+ depth = depth + countConsumedStack(prevInst);
+ sb.append('\n').append(prev).append(" (depth:").append(depth).append(')');
if (depth < 1) {
- throw new CFGBuilderException("Invalid stack at " + prev + " when checking " + handle);
+ throw new CFGBuilderException("Invalid stack at " + prev + " when checking " + handle + sb);
}
if (depth == 1) {
InstructionHandle prevPrev = prev.getPrev();
|
This modifies spotbugsTestCases/build.gradle to add Groovy support and cleans up / refactors the AbstractIntegrationTest to read .class files generated by the Groovy compiler. At the same time simplifies some logic and switches use of java.io.File over to the java.nio.file package instead.
The point is that the current code does not consider Not sure why Groovy prefers |
This modifies spotbugsTestCases/build.gradle to add Groovy support and cleans up / refactors the AbstractIntegrationTest to read .class files generated by the Groovy compiler. At the same time simplifies some logic and switches use of java.io.File over to the java.nio.file package instead.
This minimal Groovy class
src/main/groovy/Class1.groovy
with Java class main method entry point and maven
pom.xml
src/main/java/Main.java
pom.xml
causes Spotbugs to crash with
I have created a minimal maven reproducible example of the above here https://github.com/tmoschou/bug-repro-spotbugs using the
spotbugs-maven-plugin
andgmavenplus-plugin
to build the mix Groovy/Java projectVersions
I am using the latest versions at the time of writing for every dependency and plugin
com.github.spotbugs:spotbugs:4.7.1
com.github.spotbugs:spotbugs-maven-plugin:4.7.1.1
org.apache.groovy:groovy-all:4.0.4
org.codehaus.gmavenplus:gmavenplus-plugin:1.13.1
Steps to reproduce.
mvn clean verify
Other notes
This seems to be an issue using
double
orlong
specifically.float
andint
are fine.I have set
maxRank
to1
.Seems related to #1386 opened two years ago (against Groovy 2) - but there has not been any activity.
Disassembled
Class1.class
usingjavap -p -l -v -c Class1
Click to expand
Decompiled
Class1.class
using IntelliJ IDEA and FernFlowerClick to expand
The text was updated successfully, but these errors were encountered: