-
Notifications
You must be signed in to change notification settings - Fork 285
For function postcondition violations, point to the problematic expression branch #5681
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
Changes from 5 commits
21a9246
0ec4c02
a0d6c9d
42faeca
eae6238
3e142d9
2c93cf4
c6c2bc3
1ecd423
6d757b4
cbb8b9b
0726bc5
ae13091
18f38f8
fb1ab6e
837f587
b460fb6
4a5bc5c
d8fa9c5
b65ec85
bbe156c
fffe0ee
e2514f5
813a5fe
50319de
597000c
243c547
aa43a4f
0d08aef
1374af2
d92ebf7
75f8b72
3823092
c2859db
5ab40e8
1a536cd
7caa143
f077794
fb3401a
8974e7f
bdbfa6e
2f0e6c9
c11f667
9887a5b
e7e7917
e5d4b67
f42b915
91597f2
bb8e2e3
51b4ff0
241d7d7
b6a9d8a
288d151
aa185cb
f78fb93
8598094
e5bcd0e
c3e2143
581ab43
8d9b434
6657f01
829ff78
c567e1d
a2fe6c5
c7ee87e
f08c17a
3f0b621
4b61176
8d816a9
e07a4e0
0a270b2
f5a7b0e
7ecfdbe
0d7402c
ea83f6d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -1431,16 +1431,16 @@ void AddWellformednessCheck(RedirectingTypeDecl decl) { | |||||||||
| // parameters of the procedure | ||||||||||
| var inParams = MkTyParamFormals(decl.TypeArgs, true); | ||||||||||
| Type baseType; | ||||||||||
| Bpl.Expr wh; | ||||||||||
| Bpl.Expr whereClause; | ||||||||||
| if (decl.Var != null) { | ||||||||||
| baseType = decl.Var.Type; | ||||||||||
| Bpl.Type varType = TrType(baseType); | ||||||||||
| wh = GetWhereClause(decl.Var.tok, new Bpl.IdentifierExpr(decl.Var.tok, decl.Var.AssignUniqueName(decl.IdGenerator), varType), baseType, etran, NOALLOC); | ||||||||||
| whereClause = GetWhereClause(decl.Var.tok, new Bpl.IdentifierExpr(decl.Var.tok, decl.Var.AssignUniqueName(decl.IdGenerator), varType), baseType, etran, NOALLOC); | ||||||||||
| // Do NOT use a where-clause in this declaration, because that would spoil the witness checking. | ||||||||||
| inParams.Add(new Bpl.Formal(decl.Var.tok, new Bpl.TypedIdent(decl.Var.tok, decl.Var.AssignUniqueName(decl.IdGenerator), varType), true)); | ||||||||||
| } else { | ||||||||||
| baseType = ((NewtypeDecl)decl).BaseType; | ||||||||||
| wh = null; | ||||||||||
| whereClause = null; | ||||||||||
| } | ||||||||||
|
|
||||||||||
| // the procedure itself | ||||||||||
|
|
@@ -1487,7 +1487,7 @@ void AddWellformednessCheck(RedirectingTypeDecl decl) { | |||||||||
| // } | ||||||||||
|
|
||||||||||
| // check well-formedness of the constraint (including termination, and delayed reads checks) | ||||||||||
| var builderInitializationArea = CheckConstraintWellformedness(decl, context, etran, locals, builder); | ||||||||||
| var builderInitializationArea = CheckConstraintWellformedness(decl, context, whereClause, etran, locals, builder); | ||||||||||
|
|
||||||||||
| // Check that the type is inhabited. | ||||||||||
| // Note, the possible witness in this check should be coordinated with the compiler, so the compiler knows how to do the initialization | ||||||||||
|
|
@@ -1507,15 +1507,16 @@ void AddWellformednessCheck(RedirectingTypeDecl decl) { | |||||||||
| CheckResultToBeInType(result.Tok, result, decl.Var.Type, locals, returnBuilder, etran); | ||||||||||
| } | ||||||||||
|
|
||||||||||
| // check that the witness is assignable to the type of the given bound variable | ||||||||||
| CheckResultToBeInType(decl.Witness.tok, decl.Witness, baseType, locals, witnessCheckBuilder, etran); | ||||||||||
| // check that the witness expression checks out | ||||||||||
| witnessExpr = Substitute(decl.Constraint, decl.Var, result); | ||||||||||
| witnessExpr = decl.Constraint != null ? Substitute(decl.Constraint, decl.Var, decl.Witness) : null; | ||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
? |
||||||||||
| witnessExpr.tok = result.Tok; | ||||||||||
| var desc = new PODesc.WitnessCheck(witnessString, witnessExpr); | ||||||||||
|
|
||||||||||
| SplitAndAssertExpression(returnBuilder, witnessExpr, etran, context, desc); | ||||||||||
| }); | ||||||||||
| codeContext = ghostCodeContext; | ||||||||||
|
|
||||||||||
| } else if (decl.WitnessKind == SubsetTypeDecl.WKind.CompiledZero) { | ||||||||||
| var witness = Zero(decl.tok, baseType); | ||||||||||
| if (witness == null) { | ||||||||||
|
|
@@ -1524,8 +1525,8 @@ void AddWellformednessCheck(RedirectingTypeDecl decl) { | |||||||||
| } else { | ||||||||||
| // before trying 0 as a witness, check that 0 can be assigned to baseType | ||||||||||
| witnessString = Printer.ExprToString(options, witness); | ||||||||||
| CheckResultToBeInType(decl.tok, witness, decl.Var.Type, locals, witnessCheckBuilder, etran, $"trying witness {witnessString}: "); | ||||||||||
| witnessExpr = Substitute(decl.Constraint, decl.Var, witness); | ||||||||||
| CheckResultToBeInType(decl.tok, witness, baseType, locals, witnessCheckBuilder, etran, $"trying witness {witnessString}: "); | ||||||||||
| witnessExpr = decl.Constraint != null ? Substitute(decl.Constraint, decl.Var, witness) : null; | ||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same question as above. I'm surprised that witnessExpr can be null even if there is a witness given. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I copied these changes from #5547. I'm afraid I don't understand them myself. @ssomayyajula do you? |
||||||||||
|
|
||||||||||
| witnessExpr.tok = decl.tok; | ||||||||||
| var desc = new PODesc.WitnessCheck(witnessString, witnessExpr); | ||||||||||
|
|
@@ -1556,7 +1557,6 @@ void AddWellformednessCheck(RedirectingTypeDecl decl) { | |||||||||
| private void SplitAndAssertExpression(BoogieStmtListBuilder witnessCheckBuilder, Expression witnessExpr, | ||||||||||
| ExpressionTranslator etran, BodyTranslationContext context, PODesc.WitnessCheck desc) { | ||||||||||
| witnessCheckBuilder.Add(new Bpl.AssumeCmd(witnessExpr.tok, etran.CanCallAssumption(witnessExpr))); | ||||||||||
| var witnessCheck = etran.TrExpr(witnessExpr); | ||||||||||
|
|
||||||||||
| var ss = TrSplitExpr(context, witnessExpr, etran, true, out var splitHappened); | ||||||||||
MikaelMayer marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||
| if (!splitHappened) { | ||||||||||
|
|
@@ -1572,13 +1572,26 @@ private void SplitAndAssertExpression(BoogieStmtListBuilder witnessCheckBuilder, | |||||||||
| } | ||||||||||
|
|
||||||||||
| private BoogieStmtListBuilder CheckConstraintWellformedness(RedirectingTypeDecl decl, BodyTranslationContext context, | ||||||||||
| ExpressionTranslator etran, List<Variable> locals, BoogieStmtListBuilder builder) { | ||||||||||
| Bpl.Expr whereClause, ExpressionTranslator etran, List<Variable> locals, BoogieStmtListBuilder builder) { | ||||||||||
| var constraintCheckBuilder = new BoogieStmtListBuilder(this, options, context); | ||||||||||
| var builderInitializationArea = new BoogieStmtListBuilder(this, options, context); | ||||||||||
| var delayer = new ReadsCheckDelayer(etran, null, locals, builderInitializationArea, constraintCheckBuilder); | ||||||||||
| delayer.DoWithDelayedReadsChecks(false, wfo => { | ||||||||||
| CheckWellformedAndAssume(decl.Constraint, wfo, locals, constraintCheckBuilder, etran, "predicate subtype constraint"); | ||||||||||
| }); | ||||||||||
| if (decl.Constraint == null) { | ||||||||||
| constraintCheckBuilder.Add(new Bpl.CommentCmd($"well-formedness of {decl.WhatKind} constraint is trivial")); | ||||||||||
| } else { | ||||||||||
| constraintCheckBuilder.Add(new Bpl.CommentCmd($"check well-formedness of {decl.WhatKind} constraint")); | ||||||||||
| if (whereClause != null) { | ||||||||||
| constraintCheckBuilder.Add(new Bpl.AssumeCmd(decl.tok, whereClause)); | ||||||||||
| } | ||||||||||
| var delayer = new ReadsCheckDelayer(etran, null, locals, builderInitializationArea, constraintCheckBuilder); | ||||||||||
| delayer.DoWithDelayedReadsChecks(false, wfo => { | ||||||||||
| CheckWellformedAndAssume(decl.Constraint, wfo, locals, constraintCheckBuilder, etran, "predicate subtype constraint"); | ||||||||||
| }); | ||||||||||
| } | ||||||||||
|
|
||||||||||
| // var delayer = new ReadsCheckDelayer(etran, null, locals, builderInitializationArea, constraintCheckBuilder); | ||||||||||
| // delayer.DoWithDelayedReadsChecks(false, wfo => { | ||||||||||
| // CheckWellformedAndAssume(decl.Constraint, wfo, locals, constraintCheckBuilder, etran, "predicate subtype constraint"); | ||||||||||
| // }); | ||||||||||
|
||||||||||
| // var delayer = new ReadsCheckDelayer(etran, null, locals, builderInitializationArea, constraintCheckBuilder); | |
| // delayer.DoWithDelayedReadsChecks(false, wfo => { | |
| // CheckWellformedAndAssume(decl.Constraint, wfo, locals, constraintCheckBuilder, etran, "predicate subtype constraint"); | |
| // }); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,4 +1,4 @@ | ||
|
|
||
| Dafny program verifier finished with 15 verified, 0 errors | ||
| Total resources used is 26054889 | ||
| Max resources used by VC is 15592113 | ||
| Dafny program verifier finished with 272 verified, 0 errors | ||
| Total resources used is 30533115 | ||
| Max resources used by VC is 2074326 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,4 +1,4 @@ | ||
|
|
||
| Dafny program verifier finished with 15 verified, 0 errors | ||
| Total resources used is 28044434 | ||
| Max resources used by VC is 16505967 | ||
| Dafny program verifier finished with 276 verified, 0 errors | ||
| Total resources used is 28989931 | ||
| Max resources used by VC is 1092418 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Useful renaming.