From b53963a791756b960b3f9ca7a738edd50eacfa56 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Thu, 2 Feb 2023 09:09:20 +0000 Subject: [PATCH] C++: QLDoc. --- .../cpp/ir/dataflow/internal/DataFlowUtil.qll | 15 +++++++ .../cpp/ir/dataflow/internal/SsaInternals.qll | 40 ++++++++++++++++++- .../dataflow/internal/SsaInternalsCommon.qll | 3 ++ 3 files changed, 57 insertions(+), 1 deletion(-) 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 0e7372a3bc3..7ee36571586 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 @@ -526,11 +526,18 @@ class SideEffectOperandNode extends Node, IndirectOperand { Expr getArgument() { result = call.getArgument(argumentIndex).getUnconvertedResultExpression() } } +/** + * INTERNAL: do not use. + * + * A node representing the value of a global variable just before returning + * from a function body. + */ class FinalGlobalValue extends Node, TFinalGlobalValue { Ssa::GlobalUse globalUse; FinalGlobalValue() { this = TFinalGlobalValue(globalUse) } + /** Gets the underlying SSA use. */ Ssa::GlobalUse getGlobalUse() { result = globalUse } override Declaration getEnclosingCallable() { result = this.getFunction() } @@ -549,11 +556,18 @@ class FinalGlobalValue extends Node, TFinalGlobalValue { override string toStringImpl() { result = globalUse.toString() } } +/** + * INTERNAL: do not use. + * + * A node representing the value of a global variable just after entering + * a function body. + */ class InitialGlobalValue extends Node, TInitialGlobalValue { Ssa::GlobalDef globalDef; InitialGlobalValue() { this = TInitialGlobalValue(globalDef) } + /** Gets the underlying SSA definition. */ Ssa::GlobalDef getGlobalDef() { result = globalDef } override Declaration getEnclosingCallable() { result = this.getFunction() } @@ -1262,6 +1276,7 @@ class VariableNode extends Node, TVariableNode { /** Gets the variable corresponding to this node. */ Variable getVariable() { result = v } + /** Gets the indirection index of this node. */ int getIndirectionIndex() { result = indirectionIndex } override Declaration getFunction() { none() } 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 a5796a2c4ae..bf9ce406249 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 @@ -34,10 +34,19 @@ private module SourceVariables { bindingset[ind] SourceVariable() { any() } + /** Gets a textual representation of this element. */ abstract string toString(); + /** + * Gets the number of loads performed on the base source variable + * to reach the value of this source variable. + */ int getIndirection() { result = ind } + /** + * Gets the base source variable (i.e., the variable without any + * indirections) of this source variable. + */ abstract BaseSourceVariable getBaseVariable(); } @@ -192,6 +201,10 @@ abstract private class DefOrUseImpl extends TDefOrUseImpl { /** Holds if this definition or use has index `index` in block `block`. */ abstract predicate hasIndexInBlock(IRBlock block, int index); + /** + * Holds if this definition (or use) has index `index` in block `block`, + * and is a definition (or use) of the variable `sv` + */ final predicate hasIndexInBlock(IRBlock block, int index, SourceVariable sv) { this.hasIndexInBlock(block, index) and sv = this.getSourceVariable() @@ -216,6 +229,10 @@ abstract private class DefOrUseImpl extends TDefOrUseImpl { */ abstract BaseSourceVariableInstruction getBase(); + /** + * Gets the base source variable (i.e., the variable without + * any indirection) of this definition or use. + */ final BaseSourceVariable getBaseSourceVariable() { this.getBase().getBaseSourceVariable() = result } @@ -437,10 +454,12 @@ class GlobalUse extends UseImpl, TGlobalUse { override FinalGlobalValue getNode() { result.getGlobalUse() = this } - override int getIndirection() { result = ind + 1 } // TODO + override int getIndirection() { result = ind + 1 } + /** Gets the global variable associated with this use. */ Cpp::GlobalOrNamespaceVariable getVariable() { result = global } + /** Gets the `IRFunction` whose body is exited from after this use. */ IRFunction getIRFunction() { result = f } final override predicate hasIndexInBlock(IRBlock block, int index) { @@ -454,6 +473,10 @@ class GlobalUse extends UseImpl, TGlobalUse { final override Cpp::Location getLocation() { result = f.getLocation() } + /** + * Gets the type of this use after specifiers have been deeply stripped + * and typedefs have been resolved. + */ Type getUnspecifiedType() { result = global.getUnspecifiedType() } override predicate isCertain() { any() } @@ -468,12 +491,16 @@ class GlobalDef extends TGlobalDef { GlobalDef() { this = TGlobalDef(global, f, indirectionIndex) } + /** Gets the global variable associated with this definition. */ Cpp::GlobalOrNamespaceVariable getVariable() { result = global } + /** Gets the `IRFunction` whose body is evaluated after this definition. */ IRFunction getIRFunction() { result = f } + /** Gets the global variable associated with this definition. */ int getIndirectionIndex() { result = indirectionIndex } + /** Holds if this definition or use has index `index` in block `block`. */ final predicate hasIndexInBlock(IRBlock block, int index) { exists(EnterFunctionInstruction enter | enter = f.getEnterFunctionInstruction() and @@ -481,21 +508,32 @@ class GlobalDef extends TGlobalDef { ) } + /** Gets the global variable associated with this definition. */ SourceVariable getSourceVariable() { sourceVariableIsGlobal(result, global, f, indirectionIndex) } + /** + * Holds if this definition has index `index` in block `block`, and + * is a definition of the variable `sv` + */ final predicate hasIndexInBlock(IRBlock block, int index, SourceVariable sv) { this.hasIndexInBlock(block, index) and sv = this.getSourceVariable() } + /** Gets the location of this element. */ final Cpp::Location getLocation() { result = f.getLocation() } + /** Gets a textual representation of this element. */ string toString() { if indirectionIndex = 0 then result = global.toString() else result = global.toString() + " indirection" } + /** + * Gets the type of this use after specifiers have been deeply stripped + * and typedefs have been resolved. + */ Type getUnspecifiedType() { result = global.getUnspecifiedType() } } diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternalsCommon.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternalsCommon.qll index 1649185309d..d848525d99c 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternalsCommon.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternalsCommon.qll @@ -325,8 +325,10 @@ newtype TBaseSourceVariable = TBaseCallVariable(AllocationInstruction call) abstract class BaseSourceVariable extends TBaseSourceVariable { + /** Gets a textual representation of this element. */ abstract string toString(); + /** Gets the type of this base source variable. */ abstract DataFlowType getType(); } @@ -441,6 +443,7 @@ predicate isModifiableAt(CppType cppType, int indirectionIndex) { } abstract class BaseSourceVariableInstruction extends Instruction { + /** Gets the base source variable accessed by this instruction. */ abstract BaseSourceVariable getBaseSourceVariable(); }