Bug #5000
closedLoopLifter NPE after updating to Saxon 10.5 EE
100%
Description
We have recently upgraded from 9.9.1.4 EE to 10.5 EE. We're experiencing now a new NullPointerException
:
java.lang.NullPointerException
at net.sf.saxon.expr.parser.LoopLifter.markDependencies(LoopLifter.java:168)
The problem goes away when disabling the loop lifting optimization, via -opt:-l
.
The origin of the exception is with some very old legacy code. Please see the attach sample, looplift_npe.zip. I have been running:
/usr/bin/java -jar /path/to/10.5/saxon-ee-10.5.jar -xsl:stylesheet.xsl -s:in.xml
The problem is with legacy.xsl
which is only included.
Note, when I comment lns 26-32 and 211-219, then the problem also goes away. I don't understand why.
Since this is very old code, I reckon the NPE is caused by some defect there, however I just can't figure it out. I think we should be able to run v10.5 without disabling the looplift optimization.
Files
Updated by Michael Kay over 3 years ago
An exception at this point in the LoopLifter always indicates a corruption in the expression tree, specifically where an expression P has a child expression C whose parent is not P. The difficulty is tracing back to where the corruption occurred. On this occasion the relevant expression is from line 26 of legacy.xml. P is the expression (data($space-count)) eq 0
, C is the subexpression data($space-count)
, and the parent expression of C is convertUntyped(data($space-count))
.
This suggests that we stripped off the "convertUntyped" because we discovered during type-checking that it wasn't needed (presumably when we established that $space-count was an untyped document node), and failed to reset the parent pointers when doing so. Alternatively it can happen that a subexpression is incorrectly referenced as a child of more than one parent, in which case an error is reported when it is reached by one of those routes. This could happen as a result of extraction of common subexpressions, because data($space-count)
is computed rather frequently.
The UntypedSequenceConverter
, it appears, is created while attempt to turn the xsl:choose
into a switch expression, and the line of code that does this is marked as having been added in response to bug 4738 (therefore, quite recently).
The problem here is that the xsl:choose
turns out not to satisfy all the conditions for conversion to a switch expression, and so the attempt is abandoned, but by then we have made anticipatory changes. We should be checking that all the conditions are satisfied before we do anything, because rolling back changes is always difficult and error-prone.
Updated by Michael Kay over 3 years ago
The problem appears to be solved by copying the data before changing it, that is change the code at OptimizerEE.trySwitch() (line 1669) from
if (((ComparisonExpression) condition).getAtomicComparer() instanceof UntypedNumericComparer) {
// Bug 4738
lhs = new UntypedSequenceConverter(lhs, BuiltInAtomicType.DOUBLE);
}
to
if (((ComparisonExpression) condition).getAtomicComparer() instanceof UntypedNumericComparer) {
// Bug 4738, 5000
lhs = new UntypedSequenceConverter(lhs.copy(new RebindingMap()), BuiltInAtomicType.DOUBLE);
}
Updated by Michael Kay over 3 years ago
- Category set to Internals
- Status changed from New to Resolved
- Assignee set to Michael Kay
- Priority changed from Low to Normal
- Applies to branch trunk added
- Fix Committed on Branch 10, trunk added
Updated by O'Neil Delpratt about 3 years ago
- Status changed from Resolved to Closed
- % Done changed from 0 to 100
- Fixed in Maintenance Release 10.6 added
Bug fix applied in the Saxon 10.6 maintenance release
Please register to edit this issue