Java: Avoid generating contradicting summary and neutral summary models.

This commit is contained in:
Michael Nebel
2024-01-11 11:28:14 +01:00
parent 03d4025b99
commit 6af0bca777
2 changed files with 17 additions and 8 deletions

View File

@@ -22,6 +22,8 @@ class Type = J::Type;
class Unit = J::Unit; class Unit = J::Unit;
class Callable = J::Callable;
private J::Method superImpl(J::Method m) { private J::Method superImpl(J::Method m) {
result = m.getAnOverride() and result = m.getAnOverride() and
not exists(result.getAnOverride()) and not exists(result.getAnOverride()) and
@@ -36,7 +38,7 @@ private predicate isInfrequentlyUsed(J::CompilationUnit cu) {
/** /**
* Holds if it is relevant to generate models for `api`. * Holds if it is relevant to generate models for `api`.
*/ */
private predicate isRelevantForModels(J::Callable api) { private predicate isRelevantForModels(Callable api) {
not isUninterestingForModels(api) and not isUninterestingForModels(api) and
not isInfrequentlyUsed(api.getCompilationUnit()) and not isInfrequentlyUsed(api.getCompilationUnit()) and
// Disregard all APIs that have a manual model. // Disregard all APIs that have a manual model.
@@ -48,7 +50,7 @@ private predicate isRelevantForModels(J::Callable api) {
/** /**
* Holds if it is relevant to generate models for `api` based on data flow analysis. * Holds if it is relevant to generate models for `api` based on data flow analysis.
*/ */
predicate isRelevantForDataFlowModels(J::Callable api) { predicate isRelevantForDataFlowModels(Callable api) {
isRelevantForModels(api) and isRelevantForModels(api) and
(not api.getDeclaringType() instanceof J::Interface or exists(api.getBody())) (not api.getDeclaringType() instanceof J::Interface or exists(api.getBody()))
} }
@@ -61,7 +63,7 @@ predicate isRelevantForTypeBasedFlowModels = isRelevantForModels/1;
* In the Standard library and 3rd party libraries it the Callables that can be called * In the Standard library and 3rd party libraries it the Callables that can be called
* from outside the library itself. * from outside the library itself.
*/ */
class TargetApiSpecific extends J::Callable { class TargetApiSpecific extends Callable {
TargetApiSpecific() { TargetApiSpecific() {
this.isPublic() and this.isPublic() and
this.fromSource() and this.fromSource() and
@@ -71,6 +73,15 @@ class TargetApiSpecific extends J::Callable {
) and ) and
isRelevantForModels(this) isRelevantForModels(this)
} }
/**
* Gets the callable that a model will be lifted to, if any.
*/
Callable lift() {
exists(Method m | m = superImpl(this) and m.fromSource() | result = m)
or
not exists(superImpl(this)) and result = this
}
} }
private string isExtensible(J::RefType ref) { private string isExtensible(J::RefType ref) {
@@ -84,9 +95,7 @@ private string typeAsModel(J::RefType type) {
} }
private J::RefType bestTypeForModel(TargetApiSpecific api) { private J::RefType bestTypeForModel(TargetApiSpecific api) {
if exists(superImpl(api)) result = api.lift().getDeclaringType()
then superImpl(api).fromSource() and result = superImpl(api).getDeclaringType()
else result = api.getDeclaringType()
} }
/** /**
@@ -200,7 +209,7 @@ string returnNodeAsOutput(DataFlowImplCommon::ReturnNodeExt node) {
/** /**
* Gets the enclosing callable of `ret`. * Gets the enclosing callable of `ret`.
*/ */
J::Callable returnNodeEnclosingCallable(DataFlowImplCommon::ReturnNodeExt ret) { Callable returnNodeEnclosingCallable(DataFlowImplCommon::ReturnNodeExt ret) {
result = DataFlowImplCommon::getNodeEnclosingCallable(ret).asCallable() result = DataFlowImplCommon::getNodeEnclosingCallable(ret).asCallable()
} }

View File

@@ -77,6 +77,6 @@ string captureFlow(DataFlowTargetApi api) {
* A neutral model is generated, if there does not exist any summary model. * A neutral model is generated, if there does not exist any summary model.
*/ */
string captureNoFlow(DataFlowTargetApi api) { string captureNoFlow(DataFlowTargetApi api) {
not exists(captureFlow(api)) and not exists(DataFlowTargetApi api0 | exists(captureFlow(api0)) and api0.lift() = api.lift()) and
result = ModelPrinting::asNeutralSummaryModel(api) result = ModelPrinting::asNeutralSummaryModel(api)
} }