C++: Unify four implementations of repeatStars. Note that the recursive approach is faster for very large strings (well over 100 stars), while the concat approach appears to be faster for short strings and does not require an upper bound.

This commit is contained in:
Geoffrey White
2024-03-25 18:06:21 +00:00
parent 95db7aa776
commit 76780d74d9
4 changed files with 12 additions and 39 deletions

View File

@@ -12,14 +12,6 @@ private import semmle.code.cpp.dataflow.ExternalFlow
private import semmle.code.cpp.ir.IR
module Input implements InputSig<DataFlowImplSpecific::CppDataFlow> {
/**
* Gets a string representing a level of indirection, for example for
* `indirection = 2`, the result is `**`.
*/
private bindingset[indirection] string indirectionString(int indirection) {
result = concat(int i | i in [1 .. indirection] | "*")
}
class SummarizedCallableBase = Function;
ArgumentPosition callbackSelfParameterPosition() { result = TDirectPosition(-1) }
@@ -33,7 +25,7 @@ module Input implements InputSig<DataFlowImplSpecific::CppDataFlow> {
string encodeReturn(ReturnKind rk, string arg) {
rk != getStandardReturnValueKind() and
result = "ReturnValue" and
arg = indirectionString(rk.(NormalReturnKind).getIndirectionIndex())
arg = repeatStars(rk.(NormalReturnKind).getIndirectionIndex())
}
string encodeContent(ContentSet cs, string arg) {
@@ -41,7 +33,7 @@ module Input implements InputSig<DataFlowImplSpecific::CppDataFlow> {
cs.isSingleton(c) and
// FieldContent indices have 0 for the address, 1 for content, so we need to subtract one.
result = "Field" and
arg = indirectionString(c.getIndirectionIndex() - 1) + c.getField().getName()
arg = repeatStars(c.getIndirectionIndex() - 1) + c.getField().getName()
)
}
@@ -58,7 +50,7 @@ module Input implements InputSig<DataFlowImplSpecific::CppDataFlow> {
*/
private bindingset[argString] TPosition decodePosition(string argString) {
exists(int indirection, string posString, int pos |
argString = indirectionString(indirection) + posString and
argString = repeatStars(indirection) + posString and
pos = AccessPath::parseInt(posString) and
(
pos >= 0 and indirection = 0 and result = TDirectPosition(pos)
@@ -98,7 +90,7 @@ module Input implements InputSig<DataFlowImplSpecific::CppDataFlow> {
result.isSingleton(c) and
token.getName() = c.getField().getName() and
// FieldContent indices have 0 for the address, 1 for content, so we need to subtract one.
token.getAnArgument() = indirectionString(c.getIndirectionIndex() - 1)
token.getAnArgument() = repeatStars(c.getIndirectionIndex() - 1)
)
}
}

View File

@@ -80,15 +80,6 @@ module NodeStars {
result = n.(FinalParameterNode).getIndirectionIndex()
}
private int maxNumberOfIndirections() { result = max(getNumberOfIndirections(_)) }
private string repeatStars(int n) {
n = 0 and result = ""
or
n = [1 .. maxNumberOfIndirections()] and
result = "*" + repeatStars(n - 1)
}
/**
* Gets the number of stars (i.e., `*`s) needed to produce the `toString`
* output for `n`.

View File

@@ -2363,16 +2363,15 @@ class Content extends TContent {
abstract predicate impliesClearOf(Content c);
}
private module ContentStars {
private int maxNumberOfIndirections() { result = max(any(Content c).getIndirectionIndex()) }
private string repeatStars(int n) {
n = 0 and result = ""
or
n = [1 .. maxNumberOfIndirections()] and
result = "*" + repeatStars(n - 1)
/**
* Gets a string consisting of `n` star characters ("*"), where n >= 0. This is
* used to represent indirection.
*/
bindingset[n] string repeatStars(int n) {
result = concat(int i | i in [1 .. n] | "*")
}
private module ContentStars {
/**
* Gets the number of stars (i.e., `*`s) needed to produce the `toString`
* output for `c`.

View File

@@ -19,15 +19,6 @@ private module SourceVariables {
ind = [0 .. countIndirectionsForCppType(base.getLanguageType()) + 1]
}
private int maxNumberOfIndirections() { result = max(SourceVariable sv | | sv.getIndirection()) }
private string repeatStars(int n) {
n = 0 and result = ""
or
n = [1 .. maxNumberOfIndirections()] and
result = "*" + repeatStars(n - 1)
}
class SourceVariable extends TSourceVariable {
BaseSourceVariable base;
int ind;