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 private import semmle.code.cpp.ir.IR
module Input implements InputSig<DataFlowImplSpecific::CppDataFlow> { 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; class SummarizedCallableBase = Function;
ArgumentPosition callbackSelfParameterPosition() { result = TDirectPosition(-1) } ArgumentPosition callbackSelfParameterPosition() { result = TDirectPosition(-1) }
@@ -33,7 +25,7 @@ module Input implements InputSig<DataFlowImplSpecific::CppDataFlow> {
string encodeReturn(ReturnKind rk, string arg) { string encodeReturn(ReturnKind rk, string arg) {
rk != getStandardReturnValueKind() and rk != getStandardReturnValueKind() and
result = "ReturnValue" and result = "ReturnValue" and
arg = indirectionString(rk.(NormalReturnKind).getIndirectionIndex()) arg = repeatStars(rk.(NormalReturnKind).getIndirectionIndex())
} }
string encodeContent(ContentSet cs, string arg) { string encodeContent(ContentSet cs, string arg) {
@@ -41,7 +33,7 @@ module Input implements InputSig<DataFlowImplSpecific::CppDataFlow> {
cs.isSingleton(c) and cs.isSingleton(c) and
// FieldContent indices have 0 for the address, 1 for content, so we need to subtract one. // FieldContent indices have 0 for the address, 1 for content, so we need to subtract one.
result = "Field" and 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) { private bindingset[argString] TPosition decodePosition(string argString) {
exists(int indirection, string posString, int pos | exists(int indirection, string posString, int pos |
argString = indirectionString(indirection) + posString and argString = repeatStars(indirection) + posString and
pos = AccessPath::parseInt(posString) and pos = AccessPath::parseInt(posString) and
( (
pos >= 0 and indirection = 0 and result = TDirectPosition(pos) pos >= 0 and indirection = 0 and result = TDirectPosition(pos)
@@ -98,7 +90,7 @@ module Input implements InputSig<DataFlowImplSpecific::CppDataFlow> {
result.isSingleton(c) and result.isSingleton(c) and
token.getName() = c.getField().getName() and token.getName() = c.getField().getName() and
// FieldContent indices have 0 for the address, 1 for content, so we need to subtract one. // 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() 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` * Gets the number of stars (i.e., `*`s) needed to produce the `toString`
* output for `n`. * output for `n`.

View File

@@ -2363,16 +2363,15 @@ class Content extends TContent {
abstract predicate impliesClearOf(Content c); abstract predicate impliesClearOf(Content c);
} }
/**
* 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 { 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 the number of stars (i.e., `*`s) needed to produce the `toString` * Gets the number of stars (i.e., `*`s) needed to produce the `toString`
* output for `c`. * output for `c`.

View File

@@ -19,15 +19,6 @@ private module SourceVariables {
ind = [0 .. countIndirectionsForCppType(base.getLanguageType()) + 1] 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 { class SourceVariable extends TSourceVariable {
BaseSourceVariable base; BaseSourceVariable base;
int ind; int ind;