C++: Add Expr.getUnconverted predicate

This gets rid of the expensive predicate
`#Cast::Conversion::getExpr_dispred#ffPlus`, I've observed to cause
memory pressure on large databases.
This commit is contained in:
Jonas Jensen
2020-02-27 14:52:42 +01:00
parent 9c06c48dc7
commit c9e56d13f7
3 changed files with 16 additions and 12 deletions

View File

@@ -442,6 +442,20 @@ class Expr extends StmtParent, @expr {
else result = this
}
/**
* Gets the unique non-`Conversion` expression `e` for which
* `this = e.getConversion*()`.
*
* For example, if called on the expression `(int)(char)x`, this predicate
* gets the expression `x`.
*/
Expr getUnconverted() {
not this instanceof Conversion and
result = this
or
result = this.(Conversion).getExpr().getUnconverted()
}
/**
* Gets the type of this expression, after any implicit conversions and explicit casts, and after resolving typedefs.
*

View File

@@ -131,10 +131,7 @@ class ExprNode extends InstructionNode {
* `Conversion`, then the result is that `Conversion`'s non-`Conversion` base
* expression.
*/
Expr getExpr() {
result.getConversion*() = instr.getConvertedResultExpression() and
not result instanceof Conversion
}
Expr getExpr() { result = instr.getUnconvertedResultExpression() }
/**
* Gets the expression corresponding to this node, if any. The returned

View File

@@ -68,14 +68,7 @@ private module Cached {
cached
Expr getInstructionUnconvertedResultExpression(Instruction instruction) {
exists(Expr converted |
result = converted.(Conversion).getExpr+()
or
result = converted
|
not result instanceof Conversion and
converted = getInstructionConvertedResultExpression(instruction)
)
result = getInstructionConvertedResultExpression(instruction).getUnconverted()
}
cached