Merge pull request #11721 from michaelnebel/csharpjava/refactorprovenance

C#/Java: Re-factor provenance related predicates.
This commit is contained in:
Michael Nebel
2023-01-12 10:50:31 +01:00
committed by GitHub
20 changed files with 269 additions and 291 deletions

View File

@@ -241,15 +241,19 @@ module Public {
}
/**
* Holds if the summary is auto generated and not manually generated.
* Holds if all the summaries that apply to `this` are auto generated and not manually created.
*/
predicate isAutoGenerated() { none() }
final predicate isAutoGenerated() { this.hasProvenance("generated") and not this.isManual() }
/**
* Holds if the summary has the given provenance where `true` is
* `generated` and `false` is `manual`.
* Holds if there exists a manual summary that applies to `this`.
*/
predicate hasProvenance(boolean generated) { none() }
final predicate isManual() { this.hasProvenance("manual") }
/**
* Holds if there exists a summary that applies to `this` that has provenance `provenance`.
*/
predicate hasProvenance(string provenance) { none() }
}
/** A callable where there is no flow via the callable. */
@@ -257,15 +261,19 @@ module Public {
NeutralCallable() { neutralElement(this, _) }
/**
* Holds if the neutral is auto generated.
* Holds if the neutral is auto generated.
*/
predicate isAutoGenerated() { neutralElement(this, true) }
predicate isAutoGenerated() { neutralElement(this, "generated") }
/**
* Holds if the neutral has the given provenance where `true` is
* `generated` and `false` is `manual`.
* Holds if there exists a manual neutral that applies to `this`.
*/
predicate hasProvenance(boolean generated) { neutralElement(this, generated) }
final predicate isManual() { this.hasProvenance("manual") }
/**
* Holds if the neutral has provenance `provenance`.
*/
predicate hasProvenance(string provenance) { neutralElement(this, provenance) }
}
}
@@ -997,12 +1005,12 @@ module Private {
private predicate relevantSummaryElementGenerated(
AccessPath inSpec, AccessPath outSpec, string kind
) {
summaryElement(this, inSpec, outSpec, kind, true) and
not summaryElement(this, _, _, _, false)
summaryElement(this, inSpec, outSpec, kind, "generated") and
not summaryElement(this, _, _, _, "manual")
}
private predicate relevantSummaryElement(AccessPath inSpec, AccessPath outSpec, string kind) {
summaryElement(this, inSpec, outSpec, kind, false)
summaryElement(this, inSpec, outSpec, kind, "manual")
or
this.relevantSummaryElementGenerated(inSpec, outSpec, kind)
}
@@ -1021,10 +1029,8 @@ module Private {
)
}
override predicate isAutoGenerated() { this.relevantSummaryElementGenerated(_, _, _) }
override predicate hasProvenance(boolean generated) {
summaryElement(this, _, _, _, generated)
override predicate hasProvenance(string provenance) {
summaryElement(this, _, _, _, provenance)
}
}

View File

@@ -66,13 +66,6 @@ DataFlowType getSyntheticGlobalType(SummaryComponent::SyntheticGlobal sg) {
result instanceof TypeObject
}
bindingset[provenance]
private boolean isGenerated(string provenance) {
provenance = "generated" and result = true
or
provenance != "generated" and result = false
}
private predicate relatedArgSpec(Callable c, string spec) {
exists(
string namespace, string type, boolean subtypes, string name, string signature, string ext
@@ -138,19 +131,17 @@ private predicate correspondingKotlinParameterDefaultsArgSpec(
/**
* Holds if an external flow summary exists for `c` with input specification
* `input`, output specification `output`, kind `kind`, and a flag `generated`
* stating whether the summary is autogenerated.
* `input`, output specification `output`, kind `kind`, and provenance `provenance`.
*/
predicate summaryElement(
SummarizedCallableBase c, string input, string output, string kind, boolean generated
SummarizedCallableBase c, string input, string output, string kind, string provenance
) {
exists(
string namespace, string type, boolean subtypes, string name, string signature, string ext,
string provenance, string originalInput, string originalOutput, Callable baseCallable
string originalInput, string originalOutput, Callable baseCallable
|
summaryModel(namespace, type, subtypes, name, signature, ext, originalInput, originalOutput,
kind, provenance) and
generated = isGenerated(provenance) and
baseCallable = interpretElement(namespace, type, subtypes, name, signature, ext) and
(
c.asCallable() = baseCallable and input = originalInput and output = originalOutput
@@ -163,13 +154,12 @@ predicate summaryElement(
}
/**
* Holds if a neutral model exists for `c`, which means that there is no
* flow through `c`. The flag `generated` states whether the model is autogenerated.
* Holds if a neutral model exists for `c` with provenance `provenance`,
* which means that there is no flow through `c`.
*/
predicate neutralElement(SummarizedCallableBase c, boolean generated) {
exists(string namespace, string type, string name, string signature, string provenance |
predicate neutralElement(SummarizedCallableBase c, string provenance) {
exists(string namespace, string type, string name, string signature |
neutralModel(namespace, type, name, signature, provenance) and
generated = isGenerated(provenance) and
c.asCallable() = interpretElement(namespace, type, false, name, signature, "")
)
}
@@ -222,16 +212,14 @@ class SourceOrSinkElement = Top;
/**
* Holds if an external source specification exists for `e` with output specification
* `output`, kind `kind`, and a flag `generated` stating whether the source specification is
* autogenerated.
* `output`, kind `kind`, and provenance `provenance`.
*/
predicate sourceElement(SourceOrSinkElement e, string output, string kind, boolean generated) {
predicate sourceElement(SourceOrSinkElement e, string output, string kind, string provenance) {
exists(
string namespace, string type, boolean subtypes, string name, string signature, string ext,
string provenance, SourceOrSinkElement baseSource, string originalOutput
SourceOrSinkElement baseSource, string originalOutput
|
sourceModel(namespace, type, subtypes, name, signature, ext, originalOutput, kind, provenance) and
generated = isGenerated(provenance) and
baseSource = interpretElement(namespace, type, subtypes, name, signature, ext) and
(
e = baseSource and output = originalOutput
@@ -243,16 +231,14 @@ predicate sourceElement(SourceOrSinkElement e, string output, string kind, boole
/**
* Holds if an external sink specification exists for `e` with input specification
* `input`, kind `kind` and a flag `generated` stating whether the sink specification is
* autogenerated.
* `input`, kind `kind` and provenance `provenance`.
*/
predicate sinkElement(SourceOrSinkElement e, string input, string kind, boolean generated) {
predicate sinkElement(SourceOrSinkElement e, string input, string kind, string provenance) {
exists(
string namespace, string type, boolean subtypes, string name, string signature, string ext,
string provenance, SourceOrSinkElement baseSink, string originalInput
SourceOrSinkElement baseSink, string originalInput
|
sinkModel(namespace, type, subtypes, name, signature, ext, originalInput, kind, provenance) and
generated = isGenerated(provenance) and
baseSink = interpretElement(namespace, type, subtypes, name, signature, ext) and
(
e = baseSink and originalInput = input

View File

@@ -26,15 +26,16 @@ private int getNumMadModeledApis(string package, string provenance) {
sc.isAutoGenerated() and
provenance = "generated"
or
// "manual-only"
sc.hasProvenance(false) and
not sc.hasProvenance(true) and
provenance = "manual"
or
// "both"
sc.hasProvenance(false) and
sc.hasProvenance(true) and
provenance = "both"
sc.isManual() and
(
if sc.hasProvenance("generated")
then
// "both"
provenance = "both"
else
// "manual-only"
provenance = "manual"
)
)
)
}

View File

@@ -78,11 +78,11 @@ class TopJdkApi extends SummarizedCallableBase {
}
/** Holds if this API has a manual summary model. */
private predicate hasManualSummary() { this.(SummarizedCallable).hasProvenance(false) }
private predicate hasManualSummary() { this.(SummarizedCallable).isManual() }
/** Holds if this API has a manual neutral model. */
private predicate hasManualNeutral() {
this.(FlowSummaryImpl::Public::NeutralCallable).hasProvenance(false)
this.(FlowSummaryImpl::Public::NeutralCallable).isManual()
}
/** Holds if this API has a manual MaD model. */