From 76780d74d96e754a18cdfd98b03962c622f95a99 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 25 Mar 2024 18:06:21 +0000 Subject: [PATCH] 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. --- .../cpp/dataflow/internal/FlowSummaryImpl.qll | 16 ++++------------ .../ir/dataflow/internal/DataFlowPrivate.qll | 9 --------- .../cpp/ir/dataflow/internal/DataFlowUtil.qll | 17 ++++++++--------- .../cpp/ir/dataflow/internal/SsaInternals.qll | 9 --------- 4 files changed, 12 insertions(+), 39 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/FlowSummaryImpl.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/FlowSummaryImpl.qll index 5a34f2bedc9..7198ce58351 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/FlowSummaryImpl.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/FlowSummaryImpl.qll @@ -12,14 +12,6 @@ private import semmle.code.cpp.dataflow.ExternalFlow private import semmle.code.cpp.ir.IR module Input implements InputSig { - /** - * 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 { 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 { 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 { */ 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 { 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) ) } } diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll index 185f82df898..04e2eee6311 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll @@ -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`. diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll index d848d1bccf7..5da6bec500c 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll @@ -2363,16 +2363,15 @@ class Content extends TContent { 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 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` * output for `c`. diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternals.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternals.qll index cd2233841f2..7eb84aefe3f 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternals.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternals.qll @@ -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;