Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Improved treatment of final fields #3495

Open
wants to merge 31 commits into
base: main
Choose a base branch
from

Conversation

mattulbrich
Copy link
Member

@mattulbrich mattulbrich commented Jul 6, 2024

Intended Change

Final fields cannot change their value after a single assignment in the constructor. In the current KeY logic, final fields are treated like normal fields stored on the heap. This is highly inefficient since heap assignments cannot have an impact on final fields at all.

The plan is hence to access final fields using a function of their own that does not depend on the heap, unlike other fields

T::select(Heap, Object, Field)   // for non-final fields
T::final(Object, Field)  // for final fields

The major challenges include

  • adapting reading of final fields in modalities
  • adapting accessing final fields in JML
  • handling constructors: they are allowed to write.

Writing must somehow be restricted since any modality could write to final fields and thus compromise proofs if thus different inconsistent values for final fields are around on a sequent.

Plan

  • Add functions for finals, add a taclet option
  • Implement rules that act upon those taclet options
  • Implement special treatment for constructors
  • Test effectiveness
  • Code cleanup
  • Document the changes

The following new items showed up:

  • Deal with prettyprinting of final fields using select. Currently o.f is the prettyprinting for both accesses.
  • Deal with parsing of final fields in JavaDL. o.f means something different now ...
  • static final fields are a challenge since they need double special treatment in parsing and prettyprinting

Type of pull request

  • Breaking change (feature that cause existing functionality to change)

The plan is to have a taclet otion to fall back to old behaviour.

Ensuring quality

To do:

  • I made sure that introduced/changed code is well documented (javadoc and inline comments).
  • I made sure that new/changed end-user features are well documented (https://github.com/KeYProject/key-docs).
  • I added new test case(s) for new functionality.
  • I have checked that runtime performance has not deteriorated.

Additional information and contact(s)

It is the modernised version of #3189.

@WolframPfeifer @wadoon

The contributions within this pull request are licensed under GPLv2 (only) for inclusion in KeY.

@mattulbrich mattulbrich self-assigned this Jul 6, 2024
@wadoon
Copy link
Member

wadoon commented Jul 6, 2024

Is #3189 now obsolete?

Interestingly, final is not so final on bytecode level.

@mattulbrich
Copy link
Member Author

Is #3189 now obsolete?

This is the commits from back then merged onto the modern main.

Interestingly, final is not so final on bytecode level.

There are a few source code level things that get lost on byte code. Also generics. Sometimes private fields are not so private in byte code. We operate on source code level and assume that all code is compiler-conformant.

... revert to heap updates in such cases.
@mattulbrich mattulbrich marked this pull request as draft July 6, 2024 21:33
@mattulbrich
Copy link
Member Author

The last commits add sound special treatment for constructors.

Copy link

codecov bot commented Dec 20, 2024

Codecov Report

Attention: Patch coverage is 59.53079% with 138 lines in your changes missing coverage. Please review.

Project coverage is 38.54%. Comparing base (c2e5da7) to head (e995740).
Report is 24 commits behind head on main.

Files with missing lines Patch % Lines
...src/main/java/de/uka/ilkd/key/pp/FinalPrinter.java 30.68% 54 Missing and 7 partials ⚠️
...a/ilkd/key/proof/init/FinalFieldCodeValidator.java 61.95% 20 Missing and 15 partials ⚠️
...kd/key/java/declaration/VariableSpecification.java 45.45% 6 Missing and 6 partials ⚠️
...ka/ilkd/key/proof/init/FinalFieldsPOExtension.java 76.66% 2 Missing and 5 partials ⚠️
.../de/uka/ilkd/key/speclang/njml/JmlTermFactory.java 0.00% 5 Missing ⚠️
...c/main/java/de/uka/ilkd/key/logic/TermBuilder.java 42.85% 2 Missing and 2 partials ⚠️
.../java/de/uka/ilkd/key/ldt/FinalHeapResolution.java 78.57% 2 Missing and 1 partial ⚠️
...e/uka/ilkd/key/rule/UseDependencyContractRule.java 0.00% 3 Missing ⚠️
...ka/ilkd/key/nparser/builder/ExpressionBuilder.java 60.00% 1 Missing and 1 partial ⚠️
...src/main/java/de/uka/ilkd/key/pp/FieldPrinter.java 89.47% 1 Missing and 1 partial ⚠️
... and 4 more
Additional details and impacted files
@@             Coverage Diff              @@
##               main    #3495      +/-   ##
============================================
+ Coverage     38.39%   38.54%   +0.15%     
- Complexity    17238    17345     +107     
============================================
  Files          2099     2103       +4     
  Lines        127342   127642     +300     
  Branches      21446    21495      +49     
============================================
+ Hits          48891    49202     +311     
+ Misses        72440    72376      -64     
- Partials       6011     6064      +53     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

it was not wrong before but not confluent. Failed the
case vstte10_05_Queue/AmortizedQueue_AmortizedQueue.key
@mattulbrich
Copy link
Member Author

Regarding the effectiveness: Julian has shown that the IPSO case study heavily relied on the feature.

Regarding the efficiency: The mean time per rule application is .74 ms compared to .76 ms on the current master. No regression observed.

@mattulbrich mattulbrich requested review from WolframPfeifer and wadoon and removed request for WolframPfeifer February 23, 2025 19:50
@mattulbrich mattulbrich marked this pull request as ready for review February 23, 2025 22:26
@mattulbrich mattulbrich added the Review Request Waiting for review label Feb 23, 2025
Copy link
Member

@WolframPfeifer WolframPfeifer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice feature, while reviewing it everything worked as expected. I have a few minor questions/remarks that should be resolved, but overall I think it is very well written and also nicely documented in code. Thanks!

@@ -232,6 +232,24 @@
noRestriction
};

/*!
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I noticed that this documentation is not shown when looking at the taclet settings in the option dialog. Apparently there is an xml file, where basically the same documentation is present. We really should unify this. But I don't want to block this, and prefer a new PR instead ...

\heuristics(simplify_enlarging)
};

referencedObjectIsCreatedRighFinalEQ {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

small typo:

Suggested change
referencedObjectIsCreatedRighFinalEQ {
referencedObjectIsCreatedRightFinalEQ {

// We know this holds because of isPOSupported:
FunctionalOperationContractPO fpo = (FunctionalOperationContractPO) abstractPO;
IProgramMethod iconstructor = fpo.getProgramMethod();
assert iconstructor instanceof ProgramMethod : "Contracts cannot have schema ";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand the message of the assertion here.

protected static boolean isJavaFieldConstant(Term fieldTerm, HeapLDT heapLDT,
Services services) {
try {
getJavaFieldConstant(fieldTerm, heapLDT, services);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the code here is correct, but really looks a bit weird (calling a getter, ignoring the result, and then returning true).

* Constructor calls must not leak 'this' to the called constructor.
*/
private void validateConstructorReference(ConstructorReference methodReference) {
// TODO We have to make sure that on non-static subclass is instantiated here
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Open TODO? Honestly I don't understand it ...

@@ -1566,6 +1567,26 @@ public void translateSetStatement(final SetStatement statement, final IProgramMe
new SpecificationRepository.JmlStatementSpec(pv, ImmutableList.of(assignee, value)));
}

/**
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Am I correct that this means that the feature works for ghost fields in exactly the same way as for Java fields (that is another edge case I did not think of so far)?

@@ -22,6 +22,9 @@
// default value for a field
alpha alpha::defaultValue;

// reading from final attributes (corr. to select for non-final fields)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand what you mean by that comment. What do you mean by "correct" here? What happens if you have a non-final field f and a for example the term int::final(o, f)? I would suppose that you can not resolve it further, but it is clearly a term that could occur in the sequent ...


// Without that created-check, it is not consistent.
\assumes(wellFormed(h),
boolean::select(h, o, java.lang.Object::<created>) = TRUE ==>)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just thought about whether we could model java.lang.Object::<created> itself as a final field ...

@@ -3632,10 +3805,11 @@
\displayname "active_attribute_access"
};

// TODO 2 variants with different taclet options
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Open TODO?

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
Review Request Waiting for review
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants