mirror of
https://github.com/github/codeql.git
synced 2026-04-28 02:05:14 +02:00
C++: IR: Fix performance of value-init ranges
On a snapshot of Postgres, evaluation of `getNextExplicitlyInitializedElementAfter#fff#antijoin_rhs#1` took forever, preventing the computation of the IR. I haven't been able to reproduce it with a small test case, but the implementation of `getNextExplicitlyInitializedElementAfter` was fragile because it called the inline predicate `ArrayAggregateLiteral.isInitialized`. It also seemed inefficient that `getNextExplicitlyInitializedElementAfter` was computed for many values of its parameters that were never needed by the caller. This commit replaces `getNextExplicitlyInitializedElementAfter` with a new predicate named `getEndOfValueInitializedRange`, which should have the same behavior but a more efficient implementation. It uses a helper predicate `getNextExplicitlyInitializedElementAfter`, which shares its name with the now-deleted predicate but has behavior that I think matches the name.
This commit is contained in:
@@ -270,7 +270,7 @@ newtype TTranslatedElement =
|
||||
not ignoreExpr(initList) and
|
||||
isFirstValueInitializedElementInRange(initList, elementIndex) and
|
||||
elementCount =
|
||||
getNextExplicitlyInitializedElementAfter(initList, elementIndex) -
|
||||
getEndOfValueInitializedRange(initList, elementIndex) -
|
||||
elementIndex
|
||||
} or
|
||||
// The initialization of a base class from within a constructor.
|
||||
@@ -322,23 +322,28 @@ newtype TTranslatedElement =
|
||||
|
||||
/**
|
||||
* Gets the index of the first explicitly initialized element in `initList`
|
||||
* whose index is greater than `afterElementIndex`. If there are no remaining
|
||||
* explicitly initialized elements in `initList`, the result is the total number
|
||||
* of elements in the array being initialized.
|
||||
* whose index is greater than `afterElementIndex`, where `afterElementIndex`
|
||||
* is a first value-initialized element in a value-initialized range in
|
||||
* `initList`. If there are no remaining explicitly initialized elements in
|
||||
* `initList`, the result is the total number of elements in the array being
|
||||
* initialized.
|
||||
*/
|
||||
private int getNextExplicitlyInitializedElementAfter(
|
||||
ArrayAggregateLiteral initList, int afterElementIndex) {
|
||||
if exists(int x |
|
||||
x > afterElementIndex and
|
||||
exists(initList.getElementExpr(x)))
|
||||
then (
|
||||
if exists(initList.getElementExpr(afterElementIndex + 1))
|
||||
then result = afterElementIndex + 1
|
||||
else result = getNextExplicitlyInitializedElementAfter(initList, afterElementIndex+1))
|
||||
else
|
||||
result = initList.getType().getUnspecifiedType().(ArrayType).getArraySize() and
|
||||
// required for binding
|
||||
initList.isInitialized(afterElementIndex)
|
||||
private int getEndOfValueInitializedRange(ArrayAggregateLiteral initList, int afterElementIndex) {
|
||||
isFirstValueInitializedElementInRange(initList, afterElementIndex) and
|
||||
not exists(getNextExplicitlyInitializedElementAfter(initList, afterElementIndex)) and
|
||||
result = initList.getType().getUnspecifiedType().(ArrayType).getArraySize()
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the index of the first explicitly initialized element in `initList`
|
||||
* whose index is greater than `afterElementIndex`, where `afterElementIndex`
|
||||
* is a first value-initialized element in a value-initialized range in
|
||||
* `initList`.
|
||||
*/
|
||||
private int getNextExplicitlyInitializedElementAfter(
|
||||
ArrayAggregateLiteral initList, int afterElementIndex) {
|
||||
isFirstValueInitializedElementInRange(initList, afterElementIndex) and
|
||||
result = min(int i | exists(initList.getElementExpr(i)) and i > afterElementIndex)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user