Skip to content

Commit ec5929d

Browse files
committed
adding an infinity catch on "throw null" in symb ex.
1 parent 46567da commit ec5929d

2 files changed

Lines changed: 27 additions & 11 deletions

File tree

key.core/src/main/java/de/uka/ilkd/key/macros/SymbolicExecutionOnlyMacro.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,12 +152,18 @@ public Name name() {
152152

153153
@Override
154154
public boolean isApprovedApp(RuleApp app, PosInOccurrence pio, Goal goal) {
155-
if(!hasModality(goal)) {
155+
if(!hasModality(goal) || isThrowNullBranch(goal)) {
156156
return false;
157157
}
158158
return isAdmittedRule(app) && super.isApprovedApp(app, pio, goal);
159159
}
160160

161+
/// Special case: Avoid infinite recursion on the "throw null" branch of tryCatchThrow
162+
/// by forbidding continuation on this branch.
163+
private boolean isThrowNullBranch(Goal goal) {
164+
return "Null reference in throw".equals(goal.node().getNodeInfo().getBranchLabel());
165+
}
166+
161167
private boolean hasModality(Goal goal) {
162168
return modalityCache.computeIfAbsent(goal.node().sequent(), this::hasModality);
163169
}

key.core/src/main/resources/de/uka/ilkd/key/proof/rules/javaRules.key

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -500,16 +500,26 @@
500500
tryCatchThrow {
501501
\find(\modality{#allmodal}{.. try { throw #se; #slist }
502502
catch ( #t #v0 ) { #slist1 } ...}\endmodality (post))
503-
\replacewith(\modality{#allmodal}{.. if ( #se == null ) {
504-
try { throw new java.lang.NullPointerException (); }
505-
catch ( #t #v0 ) { #slist1 }
506-
} else if ( #se instanceof #t ) {
507-
#t #v0;
508-
#v0 = (#t) #se;
509-
#slist1
510-
} else {
511-
throw #se;
512-
} ...}\endmodality (post))
503+
504+
// Case NPE: throwing null fails:
505+
"Null reference in throw":
506+
\replacewith(\modality{#allmodal}{..
507+
try { throw new java.lang.NullPointerException (); }
508+
catch ( #t #v0 ) { #slist1 } ... }\endmodality (post))
509+
\add( #se = null ==> ) ;
510+
511+
// Case catch or throw:
512+
"Normal execution" [main]:
513+
\replacewith(\modality{#allmodal}{..
514+
if ( #se instanceof #t ) {
515+
#t #v0;
516+
#v0 = (#t) #se;
517+
#slist1
518+
} else {
519+
throw #se;
520+
} ...}\endmodality (post))
521+
\add( ==> #se = null )
522+
513523
\heuristics(simplify_prog)
514524
\displayname "tryCatchThrow"
515525
};

0 commit comments

Comments
 (0)