public override void OnUnreachableCode(Implementation impl) { if (HasRequiresFalse(impl)) return; bool hasIFUnreachable = false; this.unreachableChildren = new Microsoft.FSharp.Collections.FSharpSet<IdentifierExpr>(new List<IdentifierExpr>()); for (int i = impl.Blocks.Count - 1; i >= 0; i--) { Block b = impl.Blocks[i]; if (HasAssertFalse(b)) { foreach (var cmd in b.Cmds) { PredicateCmd pred = cmd as PredicateCmd; if (pred != null) { NAryExpr nary = pred.Expr as NAryExpr; if (nary != null) { FunctionCall f = nary.Fun as FunctionCall; if (f != null && f.Func.Name == "$expect_unreachable_master") { this.unreachableMasters = this.unreachableMasters.Add(f.Func.InParams.Last() as IdentifierExpr); hasIFUnreachable = true; } else if (f != null && f.Func.Name == "$expect_unreachable_child") { this.unreachableChildren = this.unreachableChildren.Add(f.Func.InParams.Last() as IdentifierExpr); hasIFUnreachable = true; } } } } } } bool hasRealUnreachable = false; foreach (var id in this.unreachableChildren) { if (!unreachableMasters.Contains(id)) hasRealUnreachable = true; } if (!hasRealUnreachable && hasIFUnreachable) { PrintSummary(VC.ConditionGeneration.Outcome.Correct); return; } var traceTokens = new List<IToken>(); for (int i = impl.Blocks.Count - 1; i >= 0; i--) { Block b = impl.Blocks[i]; foreach (var cmd in b.Cmds) { PredicateCmd pred = cmd as PredicateCmd; if (pred != null) { NAryExpr nary = pred.Expr as NAryExpr; if (nary != null) { FunctionCall f = nary.Fun as FunctionCall; if (f != null && f.Func.Name == "$expect_unreachable") return; // Just restoring what existed. This is keeping some potentially easy to let through soundness warnings... } } } if (!IsTokenWithoutLocation(b.TransferCmd.tok)) traceTokens.Add(b.TransferCmd.tok); else { for (int j = b.Cmds.Length - 1; j >= 0; j--) { if (!IsTokenWithoutLocation(b.Cmds[j].tok)) { traceTokens.Add(b.Cmds[j].tok); break; } } } } PrintSummary(VC.ConditionGeneration.Outcome.Correct); // it is correct, but this.ReportUnreachable(traceTokens); }
public override void OnUnreachableCode(Implementation impl) { if (HasRequiresFalse(impl)) { return; } bool hasIFUnreachable = false; this.unreachableChildren = new Microsoft.FSharp.Collections.FSharpSet <IdentifierExpr>(new List <IdentifierExpr>()); for (int i = impl.Blocks.Count - 1; i >= 0; i--) { Block b = impl.Blocks[i]; if (HasAssertFalse(b)) { foreach (var cmd in b.Cmds) { PredicateCmd pred = cmd as PredicateCmd; if (pred != null) { NAryExpr nary = pred.Expr as NAryExpr; if (nary != null) { FunctionCall f = nary.Fun as FunctionCall; if (f != null && f.Func.Name == "$expect_unreachable_master") { this.unreachableMasters = this.unreachableMasters.Add(f.Func.InParams.Last() as IdentifierExpr); hasIFUnreachable = true; } else if (f != null && f.Func.Name == "$expect_unreachable_child") { this.unreachableChildren = this.unreachableChildren.Add(f.Func.InParams.Last() as IdentifierExpr); hasIFUnreachable = true; } } } } } } bool hasRealUnreachable = false; foreach (var id in this.unreachableChildren) { if (!unreachableMasters.Contains(id)) { hasRealUnreachable = true; } } if (!hasRealUnreachable && hasIFUnreachable) { PrintSummary(VC.ConditionGeneration.Outcome.Correct); return; } var traceTokens = new List <IToken>(); for (int i = impl.Blocks.Count - 1; i >= 0; i--) { Block b = impl.Blocks[i]; foreach (var cmd in b.Cmds) { PredicateCmd pred = cmd as PredicateCmd; if (pred != null) { NAryExpr nary = pred.Expr as NAryExpr; if (nary != null) { FunctionCall f = nary.Fun as FunctionCall; if (f != null && f.Func.Name == "$expect_unreachable") { return; // Just restoring what existed. This is keeping some potentially easy to let through soundness warnings... } } } } if (!IsTokenWithoutLocation(b.TransferCmd.tok)) { traceTokens.Add(b.TransferCmd.tok); } else { for (int j = b.Cmds.Length - 1; j >= 0; j--) { if (!IsTokenWithoutLocation(b.Cmds[j].tok)) { traceTokens.Add(b.Cmds[j].tok); break; } } } } PrintSummary(VC.ConditionGeneration.Outcome.Correct); // it is correct, but this.ReportUnreachable(traceTokens); }