mirror of
https://github.com/github/codeql.git
synced 2025-12-24 04:36:35 +01:00
C++: Create an abstract class to control debug 'toString' output for dataflow nodes.
This commit is contained in:
@@ -6,6 +6,7 @@ private import semmle.code.cpp.ir.internal.IRCppLanguage
|
||||
private import SsaInternals as Ssa
|
||||
private import DataFlowImplCommon as DataFlowImplCommon
|
||||
private import codeql.util.Unit
|
||||
import Node0ToString
|
||||
|
||||
cached
|
||||
private module Cached {
|
||||
@@ -138,11 +139,7 @@ abstract class InstructionNode0 extends Node0Impl {
|
||||
|
||||
override DataFlowType getType() { result = getInstructionType(instr, _) }
|
||||
|
||||
override string toStringImpl() {
|
||||
if instr.(InitializeParameterInstruction).getIRVariable() instanceof IRThisVariable
|
||||
then result = "this"
|
||||
else result = instr.getAst().toString()
|
||||
}
|
||||
override string toStringImpl() { result = instructionToString(instr) }
|
||||
|
||||
override Location getLocationImpl() {
|
||||
if exists(instr.getAst().getLocation())
|
||||
@@ -187,11 +184,7 @@ abstract class OperandNode0 extends Node0Impl {
|
||||
|
||||
override DataFlowType getType() { result = getOperandType(op, _) }
|
||||
|
||||
override string toStringImpl() {
|
||||
if op.getDef().(InitializeParameterInstruction).getIRVariable() instanceof IRThisVariable
|
||||
then result = "this"
|
||||
else result = op.getDef().getAst().toString()
|
||||
}
|
||||
override string toStringImpl() { result = operandToString(op) }
|
||||
|
||||
override Location getLocationImpl() {
|
||||
if exists(op.getDef().getAst().getLocation())
|
||||
|
||||
@@ -486,10 +486,13 @@ class Node extends TIRDataFlowNode {
|
||||
}
|
||||
|
||||
private string toExprString(Node n) {
|
||||
result = n.asExpr(0).toString()
|
||||
or
|
||||
not exists(n.asExpr()) and
|
||||
result = n.asIndirectExpr(0, 1).toString() + " indirection"
|
||||
isDebugMode() and
|
||||
(
|
||||
result = n.asExpr(0).toString()
|
||||
or
|
||||
not exists(n.asExpr()) and
|
||||
result = n.asIndirectExpr(0, 1).toString() + " indirection"
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
/**
|
||||
* This file activates debugging mode for dataflow node printing.
|
||||
*/
|
||||
|
||||
private import Node0ToString
|
||||
|
||||
private class DebugNode0ToString extends Node0ToString {
|
||||
final override predicate isDebugMode() { any() }
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
/**
|
||||
* This file contains the abstract class that serves as the base class for
|
||||
* dataflow node printing.
|
||||
*
|
||||
* By default, a non-debug string is produced. However, a debug-friendly
|
||||
* string can be produced by importing `DebugPrinting.qll`.
|
||||
*/
|
||||
|
||||
private import semmle.code.cpp.ir.IR
|
||||
private import codeql.util.Unit
|
||||
|
||||
/**
|
||||
* A class to control whether a debugging version of instructions and operands
|
||||
* should be printed as part of the `toString` output of dataflow nodes.
|
||||
*
|
||||
* To enable debug printing import the `DebugPrinting.ql` file. By default,
|
||||
* non-debug output will be used.
|
||||
*/
|
||||
class Node0ToString extends Unit {
|
||||
abstract predicate isDebugMode();
|
||||
|
||||
private string normalInstructionToString(Instruction i) {
|
||||
not this.isDebugMode() and
|
||||
if i.(InitializeParameterInstruction).getIRVariable() instanceof IRThisVariable
|
||||
then result = "this"
|
||||
else result = i.getAst().toString()
|
||||
}
|
||||
|
||||
private string normalOperandToString(Operand op) {
|
||||
not this.isDebugMode() and
|
||||
if op.getDef().(InitializeParameterInstruction).getIRVariable() instanceof IRThisVariable
|
||||
then result = "this"
|
||||
else result = op.getDef().getAst().toString()
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the string that should be used by `InstructionNode.toString`
|
||||
*/
|
||||
string instructionToString(Instruction i) {
|
||||
if this.isDebugMode()
|
||||
then result = i.getDumpString()
|
||||
else result = this.normalInstructionToString(i)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the string that should be used by `OperandNode.toString`.
|
||||
*/
|
||||
string operandToString(Operand op) {
|
||||
if this.isDebugMode()
|
||||
then result = op.getDumpString() + " @ " + op.getUse().getResultId()
|
||||
else result = this.normalOperandToString(op)
|
||||
}
|
||||
}
|
||||
|
||||
private class NoDebugNode0ToString extends Node0ToString {
|
||||
final override predicate isDebugMode() { none() }
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the string that should be used by `OperandNode.toString`.
|
||||
*/
|
||||
string operandToString(Operand op) { result = any(Node0ToString nts).operandToString(op) }
|
||||
|
||||
/**
|
||||
* Gets the string that should be used by `InstructionNode.toString`
|
||||
*/
|
||||
string instructionToString(Instruction i) { result = any(Node0ToString nts).instructionToString(i) }
|
||||
|
||||
/**
|
||||
* Holds if debugging mode is enabled.
|
||||
*
|
||||
* In debug mode the `toString` on dataflow nodes is more expensive to compute,
|
||||
* but gives more precise information about the different dataflow nodes.
|
||||
*/
|
||||
predicate isDebugMode() { not any(Node0ToString nts).isDebugMode() }
|
||||
Reference in New Issue
Block a user