[Bug]: spoon-dataflow throw NPE on Anonymous classes
- Dominant language
- Java
- Stars
- 2k
- Forks
- 392
- Avg merge
- 11h 24m
- Merged PRs (30d)
- 36
Description
### Describe the bug
I tried [spoon-dataflow](https://github.com/INRIA/spoon/tree/master/spoon-dataflow) on a small Java code.
The bug arises when an object is passed to Z3 solver raising an NPE.
I identified that writing something such as the following is problematic :
```java
/** Complete an approved transaction
*
* @return receipt to be printed for this transaction
* @exception CustomerConsole.Cancelled if customer cancelled or
* transaction timed out
*/
protected Receipt completeTransaction() throws CustomerConsole.Cancelled
{
atm.getEnvelopeAcceptor().acceptEnvelope();
Status status = atm.getNetworkToBank().sendMessage(
new Message(Message.COMPLETE_DEPOSIT,
card, pin, serialNumber, -1, to, amount),
balances);
return new Receipt(this.atm, this.card, this, this.balances) {
{
detailsPortion = new String[2];
detailsPortion[0] = "DEPOSIT TO: " +
AccountInformation.ACCOUNT_ABBREVIATIONS[to];
detailsPortion[1] = "AMOUNT: " + amount.toString();
}
};
}
```
The above extract is from the source code mentioned below. The anonymous class being defined as a subclass of the abstract class Receipt is raising an NPE. This pattern is found elsewhere in the code related to the class Receipt.
Related issue to spoon-dataflow https://github.com/INRIA/spoon/issues/5088 https://github.com/INRIA/spoon/issues/4017
### Source code you are trying to analyze/transform
```Java
See whole code from [https://www.math-cs.gordon.edu/courses/cps122/ATMExample/](https://www.math-cs.gordon.edu/courses/cps122/ATMExample/)
```
### Source code for your Spoon processing
```Java
See [here](https://github.com/INRIA/spoon/blob/master/spoon-dataflow/src/main/java/fr/inria/spoon/dataflow/Main.java)
```
### Actual output
```Java
SLF4J(W): No SLF4J providers were found.
SLF4J(W): Defaulting to no-operation (NOP) logger implementation
SLF4J(W): See https://www.slf4j.org/codes.html#noProviders for further details.
Analyzing class: ATMApplet
Analyzing method: init
Analyzing class: ATMMain
Analyzing method: main
Analyzing class: ATMMain$1
Analyzing method: actionPerformed
Analyzing class: ATMMain$2
Analyzing method: windowClosing
Analyzing class: atm.ATM
Analyzing method: run
Analyzing method: switchOn
Analyzing method: switchOff
Analyzing method: cardInserted
Analyzing method: getID
Analyzing method: getPlace
Analyzing method: getBankName
Analyzing method: getCardReader
Analyzing method: getCashDispenser
Analyzing method: getCustomerConsole
Analyzing method: getEnvelopeAcceptor
Analyzing method: getLog
Analyzing method: getNetworkToBank
Analyzing method: getOperatorPanel
Analyzing method: getReceiptPrinter
Analyzing method: performStartup
Analyzing method: performShutdown
Analyzing class: atm.Session
Analyzing method: performSession
Analyzing method: setPIN
Analyzing class: atm.physical.CardReader
Analyzing method: readCard
Analyzing method: ejectCard
Analyzing method: retainCard
Analyzing class: atm.physical.CashDispenser
Analyzing method: setInitialCash
Analyzing method: checkCashOnHand
Analyzing method: dispenseCash
Analyzing class: atm.physical.CustomerConsole
Analyzing method: display
Analyzing method: readPIN
Analyzing method: readMenuChoice
Analyzing method: readAmount
Analyzing class: atm.physical.CustomerConsole$Cancelled
Analyzing class: atm.physical.EnvelopeAcceptor
Analyzing method: acceptEnvelope
Analyzing class: atm.physical.Log
Analyzing method: logSend
Analyzing method: logResponse
Analyzing method: logCashDispensed
Analyzing method: logEnvelopeAccepted
Analyzing class: atm.physical.NetworkToBank
Analyzing method: openConnection
Analyzing method: closeConnection
Analyzing method: sendMessage
Analyzing class: atm.physical.OperatorPanel
Analyzing method: getInitialCash
Analyzing class: atm.physical.ReceiptPrinter
Analyzing method: printReceipt
Analyzing class: atm.transaction.Deposit
Analyzing method: getSpecificsFromCustomer
Analyzing method: completeTransaction
Analyzing class: atm.transaction.Deposit$1
Exception in thread "main" java.lang.NullPointerException: Cannot invoke "com.microsoft.z3.Z3Object.getContext()" because "other" is null
at com.microsoft.z3.Context.checkContextMatch(Context.java:4298)
at com.microsoft.z3.Context.mkStore(Context.java:1789)
at fr.inria.spoon.dataflow.memory.Memory.writeArray(Memory.java:107)
at fr.inria.spoon.dataflow.scanners.DataFlowScanner.visitAssignment(DataFlowScanner.java:1003)
at fr.inria.spoon.dataflow.scanners.DataFlowScanner.visitCtAssignment(DataFlowScanner.java:1026)
at spoon.support.reflect.code.CtAssignmentImpl.accept(CtAssignmentImpl.java:45)
at spoon.reflect.visitor.CtScanner.scan(CtScanner.java:199)
at spoon.reflect.visitor.CtScanner.scan(CtScanner.java:189)
at spoon.reflect.visitor.CtScanner.scan(CtScanner.java:154)
at spoon.reflect.visitor.CtScanner.visitCtBlock(CtScanner.java:326)
at spoon.support.reflect.code.CtBlockImpl.accept(CtBlockImpl.java:58)
at spoon.reflect.visitor.CtScanner.scan(CtScanner.java:199)
at fr.inria.spoon.dataflow.scanners.DataFlowScanner.visitMethod(DataFlowScanner.java:888)
at fr.inria.spoon.dataflow.scanners.DataFlowScanner.visitCtAnonymousExecutable(DataFlowScanner.java:845)
at spoon.support.reflect.declaration.CtAnonymousExecutableImpl.accept(CtAnonymousExecutableImpl.java:37)
at spoon.reflect.visitor.CtScanner.scan(CtScanner.java:199)
at spoon.reflect.visitor.CtScanner.scan(CtScanner.java:189)
at spoon.reflect.visitor.CtScanner.scan(CtScanner.java:154)
at spoon.reflect.visitor.CtScanner.visitCtClass(CtScanner.java:363)
at fr.inria.spoon.dataflow.scanners.DataFlowScanner.visitCtClass(DataFlowScanner.java:835)
at spoon.support.reflect.declaration.CtClassImpl.accept(CtClassImpl.java:63)
at spoon.reflect.visitor.CtScanner.scan(CtScanner.java:199)
at spoon.reflect.visitor.CtScanner.scan(CtScanner.java:189)
at spoon.reflect.visitor.CtScanner.visitCtNewClass(CtScanner.java:642)
at fr.inria.spoon.dataflow.scanners.DataFlowScanner.visitCtNewClass(DataFlowScanner.java:663)
at spoon.support.reflect.code.CtNewClassImpl.accept(CtNewClassImpl.java:25)
at spoon.reflect.visitor.CtScanner.scan(CtScanner.java:199)
at fr.inria.spoon.dataflow.scanners.DataFlowScanner.visitCtReturn(DataFlowScanner.java:781)
at spoon.support.reflect.code.CtReturnImpl.accept(CtReturnImpl.java:27)
at spoon.reflect.visitor.CtScanner.scan(CtScanner.java:199)
at spoon.reflect.visitor.CtScanner.scan(CtScanner.java:189)
at spoon.reflect.visitor.CtScanner.scan(CtScanner.java:154)
at spoon.reflect.visitor.CtScanner.visitCtBlock(CtScanner.java:326)
at spoon.support.reflect.code.CtBlockImpl.accept(CtBlockImpl.java:58)
at spoon.reflect.visitor.CtScanner.scan(CtScanner.java:199)
at fr.inria.spoon.dataflow.scanners.DataFlowScanner.visitMethod(DataFlowScanner.java:888)
at fr.inria.spoon.dataflow.scanners.DataFlowScanner.visitCtMethod(DataFlowScanner.java:910)
at spoon.support.reflect.declaration.CtMethodImpl.accept(CtMethodImpl.java:59)
at spoon.reflect.visitor.CtScanner.scan(CtScanner.java:199)
at spoon.reflect.visitor.CtScanner.scan(CtScanner.java:189)
at spoon.reflect.visitor.CtScanner.scan(CtScanner.java:154)
at spoon.reflect.visitor.CtScanner.visitCtClass(CtScanner.java:363)
at fr.inria.spoon.dataflow.scanners.DataFlowScanner.visitCtClass(DataFlowScanner.java:835)
at spoon.support.reflect.declaration.CtClassImpl.accept(CtClassImpl.java:63)
at spoon.reflect.visitor.CtScanner.scan(CtScanner.java:199)
at fr.inria.spoon.dataflow.Main.main(Main.java:81)
```
### Expected output
```Java
I expected no NPE and for the analysis to proceed normally.
```
### Spoon Version
11.2.0
### JVM Version
21
### What operating system are you using?
Ubuntu 22.04
Contributor guide
Assessment
This issue has not been assessed yet.